cyclic looping with [0 == object] whileFalse: [object := object
nextObject].
John M McIntosh
johnmci at smalltalkconsulting.com
Mon Nov 5 18:26:59 UTC 2007
Consider that memory is allocated from a low address to a high address.
Given the method below, we invoke "someObject" which technically is
misnamed since it actually returns the first object at the lowest
memory address. It's doubtful that object
will ever be garbage collected so asking for self someObject will
always return the same object across every image startup.
allObjectsDo: aBlock
"Evaluate the argument, aBlock, for each object in the system
excluding SmallIntegers."
| object |
object _ self someObject.
[0 == object]
whileFalse: [aBlock value: object.
object _ object nextObject]
nextObject then returns the object found after the location of the
object that is the receiver. In theory this object is older.
Now the trick here is that as we are iterating over objects from old
to new, we must NOT be creating objects that will continue to
grow the image, if for example you allocate a new object for each
nextObject processing you won't complete the loop.
Cyclic?
I believe if you become object, thus changing object from an new
object to an old object, thus changing the memory location from
an new higher address to an older object in lower address space you
are making a cycle.
In the code below I wonder what removeProperty does?
On Nov 5, 2007, at 9:39 AM, Rob Withers wrote:
> What gaurantees that doing loops with #nextObject won't cause
> cyclic looping whereby you process the same set of objects over and
> over again?
>
> The work I was doing was testing changing the parser to eliminate
> #ifTrue: macros from compiled methods and recompiled the entire
> image. I saved the image. When I started the image it was
> frozen. I broke into it and it was looping in the method
> CommandHistory class>>#forgetAllGrabCommandsFrom:. I took the loop
> and modified it slightly to see what it was processing:
>
> | object count objects |
> objects := OrderedCollection new: 1000000.
> count := 0.
> object _ nil.
> [0 == object or: [count > 500000]] whileFalse: [
> count := count + 1.
> objects add: object.
> object isMorph ifTrue: [object removeProperty:
> #undoGrabCommand].
> object _ object nextObject].
> objects
>
> It was looping through objects defined by this loop, block contexts
> defined by my change to #ifTrue: bytecodes - they now create block
> contexts.
>
> [] in UndefinedObject>>DoIt {[object removeProperty:
> #undoGrabCommand]}
> [] in UndefinedObject>>DoIt {[count > 500000]}
> OrderedCollection>>add:
> OrderedCollection>>addLast:
> [] in OrderedCollection>>addLast: {[self makeRoomAtLast]}
> False>>or:
> [] in UndefinedObject>>DoIt {[object removeProperty:
> #undoGrabCommand]}
> [] in UndefinedObject>>DoIt {[count > 500000]}
> . . .
>
> What guarantee is there supposed to be that #nextObject won't loop
> back into a cycle? What did I do to break that guarantee and how
> can I reestablish it?
>
> cheers,
> Rob
>
--
========================================================================
===
John M. McIntosh <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
========================================================================
===
More information about the Squeak-dev
mailing list
|