cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Rob Withers
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


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Mathieu SUEN
On Nov 5, 2007, at 6:39 PM, 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


I think your test is wrong 0 == object while always evaluate to false.
#nextObject return the nextObject in memory. But integer are not  
object in memory they are pointer (need to be confirm).


So you could try:

| object count objects |
    objects := OrderedCollection new: 1000000.
    count := 0.
    object := nil.
    firstObject := object
    [firstObject == object or: [count > 500000]] whileFalse: [
        count := count + 1.
        objects add: object.
        object isMorph ifTrue: [object removeProperty:  
#undoGrabCommand].
        object _ object nextObject].
    objects

HTH

        Mth

>
> 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
>


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Tom Phoenix
In reply to this post by Rob Withers
On 11/5/07, Rob Withers <[hidden email]> 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?

I think that would be the surrounding code. Certainly sending
#nextObject can't always succeed; it should eventually run out of real
objects and return zero. If you send #nextObject to 0, a SmallInteger,
it should fail for sure.

>    object _ nil.
>     [0 == object or: [count > 500000]] whileFalse: [

This should drop out when 0 is encountered, or when 500000 objects
have been counted. The first should eventually happen, and so should
the second. Are you sure you let this loop run long enough?

But I've got to say it seems odd that the loop starts at nil. Most
users of #nextObject don't use it like that, since nil isn't
guaranteed to be at any particular place in the enumeration of all
objects. Shouldn't it be something like this?

  object := self someObject.

> What guarantee is there supposed to be that #nextObject won't loop back into
> a cycle?

Zero is the guarantee.

> What did I do to break that guarantee and how can I reestablish
> it?

I don't think you broke it, unless you redefined
SmallInteger>>nextObject or something like that.

Hope this helps!

--Tom Phoenix

Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Tom Phoenix
In reply to this post by Mathieu SUEN
On 11/5/07, Mathieu Suen <[hidden email]> wrote:

> I think your test is wrong 0 == object while always evaluate to false.
> #nextObject return the nextObject in memory. But integer are not
> object in memory they are pointer (need to be confirm).

You've almost got the right idea; #nextObject doesn't return
SmallIntegers normally, just items from the object memory. But it does
return 0 at the end, as the indicator that there are no more objects
to enumerate. Of course nil can't be returned to mean no more elements
because it is one of the objects in memory that #nextObject actually
does return. If a programmer were to invoke SmallInteger>>nextObject,
that method should use #shouldNotImplement or something similar to
stop the potential infinite loop.

Additionally, remembering the initial object so as to recognize it
when it "comes around again" doesn't generally work. After all, once
the last SmallInteger is incremented, it becomes some LargeInteger,
which is a new object in memory, so #nextObject would continue on from
that one toward the end of the object memory, likely never returning
to the initial object. That's why users of #nextObject always check
whether it returns 0.

Cheers!

--Tom Phoenix

Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

johnmci
In reply to this post by Rob Withers
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 <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Tom Phoenix
In reply to this post by Rob Withers
On 11/5/07, Rob Withers <[hidden email]> wrote:

>     | 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

Now that I look at this code again, I see more. (What's the last line
supposed to be doing?) The method looks to be building a collection of
all (or up to half a million) objects in object memory, for no
apparent reason. As a side effect, or maybe its main effect, it
affects some Morphs.

Let's take care of the Morphs first. You probably want to process all
of them, not just many of them, so maybe something like this:

  Morph allSubInstancesDo: [:m |
    m removeProperty: #undoGrabCommand ].

If you really want a collection of all (or up to half a million)
objects from memory, that's easily done as well, built around
something like

  SystemNavigation default allObjectsDo: [:ob | "....whatever...." ].

But there's probably a better way to do what you want to do than to
build a collection of most of the items in the object memory.

Cheers!

--Tom Phoenix

Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := objectnextObject].

Rob Withers
In reply to this post by Tom Phoenix
Tom, the original loop that was looping forever was the method
#forgetAllGrabCommandsFrom:

    | object |
    object _ starter.
    [
        [0 == object] whileFalse: [
            object isMorph ifTrue: [object removeProperty:
#undoGrabCommand].
            object _ object nextObject].
        ] ifError: [:err :rcvr | "object is obsolete"
            self forgetAllGrabCommandsFrom: object nextObject].

where starter was set to "self someObject".   more below...

----- Original Message -----
From: "Tom Phoenix" <[hidden email]>


> On 11/5/07, Rob Withers <[hidden email]> 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?
>
> I think that would be the surrounding code. Certainly sending
> #nextObject can't always succeed; it should eventually run out of real
> objects and return zero. If you send #nextObject to 0, a SmallInteger,
> it should fail for sure.

I thought of a possibility.  It could be that I am creating objects
(BlockContexts and MethodContexts) as fast as I process them in this loop.
If the loop is creating objects, then they are bound to be at the end of
memory and I am bound to not be able to catch up to them.  In this case, my
#ifTrue: msg is a real msg creating a real BlockContext each time through
the loop, because of my Compiler changes, and the associated MethodContexts
are being created too.  (My addition of
anOrderedCollection>>#add:/#addLast:/#grow... are being recorded as well).
Each time through a new instance of the BlockContext is being created.

That sucks.  I can't do anything about it.

>
>>    object _ nil.
>>     [0 == object or: [count > 500000]] whileFalse: [
>
> This should drop out when 0 is encountered, or when 500000 objects
> have been counted. The first should eventually happen, and so should
> the second. Are you sure you let this loop run long enough?

My modified loop does stop because of count > 500000.  Then I was able to
see the cyclic looping.

>
> But I've got to say it seems odd that the loop starts at nil. Most
> users of #nextObject don't use it like that, since nil isn't
> guaranteed to be at any particular place in the enumeration of all
> objects. Shouldn't it be something like this?
>
>  object := self someObject.

I switched to this.


>> What guarantee is there supposed to be that #nextObject won't loop back
>> into
>> a cycle?
>
> Zero is the guarantee.
>
>> What did I do to break that guarantee and how can I reestablish
>> it?
>
> I don't think you broke it, unless you redefined
> SmallInteger>>nextObject or something like that.
>
> Hope this helps!

It helps me understand!  Thanks!  I don't know what I can do about it.

Cheers,
Rob


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := objectnextObject].

Rob Withers
In reply to this post by Tom Phoenix

----- Original Message -----
From: "Tom Phoenix" <[hidden email]>
To: "The general-purpose Squeak developers list"
<[hidden email]>
Sent: Monday, November 05, 2007 10:40 AM
Subject: Re: cyclic looping with [0 == object] whileFalse: [object :=
objectnextObject].


> On 11/5/07, Rob Withers <[hidden email]> wrote:
>
>>     | 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
>
> Now that I look at this code again, I see more. (What's the last line
> supposed to be doing?) The method looks to be building a collection of
> all (or up to half a million) objects in object memory, for no
> apparent reason. As a side effect, or maybe its main effect, it
> affects some Morphs.

This was only my method of detecting whether there was a cycle in the
objects it was processing.  That's all.  Now why they don't just do:

>  Morph allSubInstancesDo: [:m |
>    m removeProperty: #undoGrabCommand ].

in #forgetAllGrabCommandsFrom: in the first place, I don't know.

Beyond this instance of using #nextObject to loop, it seems that if objects
are created inside of that loop, then it may loop forever.

Cheers,
Rob


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := objectnextObject].

johnmci
In reply to this post by Rob Withers

On Nov 5, 2007, at 10:44 AM, Rob Withers wrote:

> I thought of a possibility.  It could be that I am creating objects  
> (BlockContexts and MethodContexts) as fast as I process them in  
> this loop. If the loop is creating objects, then they are bound to  
> be at the end of memory and I am bound to not be able to catch up  
> to them.  In this case, my #ifTrue: msg is a real msg creating a  
> real BlockContext each time through the loop, because of my  
> Compiler changes, and the associated MethodContexts are being  
> created too.  (My addition of anOrderedCollection>>#add:/#addLast:/
> #grow... are being recorded as well). Each time through a new  
> instance of the BlockContext is being created.
>
> That sucks.  I can't do anything about it.

As an optimization methodContexts are recycled and reused, this  
feature decreases the time take
to make a new context. When a method returns the local context is  
then stuffed onto the free context chain.
However on a GC the free context chain is GCed also. So usually you  
are not making a new object (MethodContexts ) for the message  
activation.


--
========================================================================
===
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

johnmci
In reply to this post by Tom Phoenix
Actually if you look at users of nextObject there is a case where you  
iterate over all the objects
doing isMorph then perform some cleanup action. I had also thought  
that doing Morph allSubInstancesDo: would
be faster.

But was surprised to see that iterating over all the object was like  
10x faster.
Why, well the nextObject is really fast...
and if you look at Behavior allInstancesDo: it actually does the  
someInstance, nextInstance dance

allInstancesDo: aBlock
        "Evaluate the argument, aBlock, for each of the current instances of  
the
        receiver.
       
        Because aBlock might change the class of inst (for example, using  
become:),
        it is essential to compute next before aBlock value: inst."
        | inst next |
        self ==  UndefinedObject ifTrue: [^ aBlock value: nil].
        inst _ self someInstance.
        [inst == nil]
                whileFalse:
                [
                next _ inst nextInstance.
                aBlock value: inst.
                inst _ next]

That uses the follow primitives in interp.c

instanceAfter: objectPointer
        "Support for instance enumeration. Return the next instance
        of the class of the given object, or nilObj if the enumeration
        is complete."
        | classPointer thisObj thisClass |
        classPointer := self fetchClassOf: objectPointer.
        thisObj := self accessibleObjectAfter: objectPointer.
        [thisObj = nil]
                whileFalse: [thisClass := self fetchClassOf: thisObj.
                        thisClass = classPointer ifTrue: [^ thisObj].
                        thisObj := self accessibleObjectAfter: thisObj].
        ^ nilObj


accessibleObjectAfter: oop
        "Return the accessible object following the given object or
        free chunk in the heap. Return nil when heap is exhausted."
        | obj |
        self inline: false.
        obj := self objectAfter: oop.
        [self oop: obj isLessThan: endOfMemory]
                whileTrue: [(self isFreeObject: obj) ifFalse: [^ obj].
                        obj := self objectAfter: obj].
        ^ nil



However given you are doing message sends, block evaluations etc in  
allInstancesDo:. Then *MILLIONS* of bytecodes  and 100 of thousands  
of method invocations run
to do the same task.  Thus in a simple loop iterating over an object  
and doing a message send to ask them if they are a Morph is *way faster*




On Nov 5, 2007, at 10:40 AM, Tom Phoenix wrote:

> Let's take care of the Morphs first. You probably want to process all
> of them, not just many of them, so maybe something like this:
>
>   Morph allSubInstancesDo: [:m |
>     m removeProperty: #undoGrabCommand ].
>
> If you really want a collection of all (or up to half a million)
> objects from memory, that's easily done as well, built around
> something like
>
>   SystemNavigation default allObjectsDo: [:ob | "....whatever...." ].
>
> But there's probably a better way to do what you want to do than to
> build a collection of most of the items in the object memory.
>
> Cheers!
>
> --Tom Phoenix
>

--
========================================================================
===
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := objectnextObject].

Mathieu SUEN
In reply to this post by johnmci
On Nov 5, 2007, at 8:18 PM, John M McIntosh wrote:

>
> On Nov 5, 2007, at 10:44 AM, Rob Withers wrote:
>
>> I thought of a possibility.  It could be that I am creating  
>> objects (BlockContexts and MethodContexts) as fast as I process  
>> them in this loop. If the loop is creating objects, then they are  
>> bound to be at the end of memory and I am bound to not be able to  
>> catch up to them.  In this case, my #ifTrue: msg is a real msg  
>> creating a real BlockContext each time through the loop, because  
>> of my Compiler changes, and the associated MethodContexts are  
>> being created too.  (My addition of anOrderedCollection>>#add:/
>> #addLast:/#grow... are being recorded as well). Each time through  
>> a new instance of the BlockContext is being created.
>>
>> That sucks.  I can't do anything about it.
>
> As an optimization methodContexts are recycled and reused, this  
> feature decreases the time take
> to make a new context. When a method returns the local context is  
> then stuffed onto the free context chain.
> However on a GC the free context chain is GCed also. So usually you  
> are not making a new object (MethodContexts ) for the message  
> activation.


But MethodContext are no more recyvled when thisContext is push one  
the stack:

pushActiveContextBytecode
        "Puts reclaimability of this context in question."

        self fetchNextBytecode.
        reclaimableContextCount := 0.
        self internalPush: activeContext.

And context are puch on the stack when a block is create.


        Mth

>
>
> --
> ======================================================================
> =====
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://
> www.smalltalkconsulting.com
> ======================================================================
> =====
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object :=objectnextObject].

Rob Withers
In reply to this post by johnmci

----- Original Message -----
From: "John M McIntosh" <[hidden email]>
To: "The general-purpose Squeak developers list"
<[hidden email]>
Sent: Monday, November 05, 2007 11:18 AM
Subject: Re: cyclic looping with [0 == object] whileFalse: [object
:=objectnextObject].


>
> On Nov 5, 2007, at 10:44 AM, Rob Withers wrote:
>
>> I thought of a possibility.  It could be that I am creating objects
>> (BlockContexts and MethodContexts) as fast as I process them in  this
>> loop. If the loop is creating objects, then they are bound to  be at the
>> end of memory and I am bound to not be able to catch up  to them.  In
>> this case, my #ifTrue: msg is a real msg creating a  real BlockContext
>> each time through the loop, because of my  Compiler changes, and the
>> associated MethodContexts are being  created too.  (My addition of
>> anOrderedCollection>>#add:/#addLast:/ #grow... are being recorded as
>> well). Each time through a new  instance of the BlockContext is being
>> created.
>>
>> That sucks.  I can't do anything about it.
>
> As an optimization methodContexts are recycled and reused, this  feature
> decreases the time take
> to make a new context. When a method returns the local context is  then
> stuffed onto the free context chain.
> However on a GC the free context chain is GCed also. So usually you  are
> not making a new object (MethodContexts ) for the message  activation.

In my test code, I am stuffing each object into an OrderedCollection, so
they won't be recycled for sure.  I'll try printing them to the transcript
to detect a 'cycle', but not hang on to them.

The question remains with the original code, which is not saving each
object, why it is stuck processing more and more objects.  As I said, I
changed the compiler to stop inlining #ifTrue: and this was the result of
that (after recompileAll).   I would like to find out why, and see if it is
something I have done wrong with #ifTrue: msg sending.

Is it as Mathieu Suen says?  Are they getting trapped in  the stack?

thanks,
Rob


Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Paolo Bonzini-2
In reply to this post by johnmci

> However given you are doing message sends, block evaluations etc in
> allInstancesDo:. Then *MILLIONS* of bytecodes  and 100 of thousands of
> method invocations run
> to do the same task.  Thus in a simple loop iterating over an object and
> doing a message send to ask them if they are a Morph is *way faster*

Unfortunately, something like this would also be slower than #nextObject:

     Morph withAllSubclassesDo: [ :each |
         inst _ each someInstance.
         [inst == nil] whileFalse:
             [next _ inst nextInstance.
             inst removeProperty: #undoGrabCommand.
             inst _ next]

because of the *huge* amount of Morph subclasses in the image.    You
are walking the object memory hundreds of times rather than one, and I
found out a few years ago (on a different computer) that using a Set (!)
and #nextObject is faster than using #nextInstance if you have about 20
subclasses (or more).

This would work for Rob however.

Paolo

Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := object nextObject].

Rob Withers

----- Original Message -----
From: "Paolo Bonzini" <[hidden email]>

> This would work for Rob however.
>
> Paolo
>

Hi Paolo,

That would work for me in this situation, yes.  Also, I thought that
Andreas' use of a marker to stop iteration would also work in this
situation.  The issue is that I caused the situation by turning off ifTrue:
inlining in the compiler (with help from others).

This is just an intermediate step to where I really want to be, which is
writing a macro which tests whether the receiver is Boolean, and if it is
then run the inline form of ifTrue:, and if it is not then run the msg send
form of ifTrue:.  This would avoid the above problem by keeping things
inlined.  I have this new compound macro coded up, compiling and some basic
tests and it works, but it makes my environment unstable.  I am getting the
emergency evaluator or outright image crashes when using it.  It is driving
me crazy, if I wasn't already.

I am attching the Compiler package that I believe will load up for those who
may be willing to help me figure this out.  After loading into a scratch
image, run 'Compiler recompileAll'.  Then debug 'FileList open'.   This will
show you one of the soft crashes (the emergency evaluator).  I suspect that
I don't have things I need to do syntax highlighting in the debugger for the
new macro code, but I am not sure if that is enough to cause crashes.  It
does strange things like switch arguments, in this case a DirectoryEntry
suddenly becomes 6.

thanks for any assistance,
Rob



SqueakElib-Compiler-rww.3.mcz (20K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: cyclic looping with [0 == object] whileFalse: [object := objectnextObject].

Rob Withers
Oh shoot.   This won't work since there are new bytecodes I have compiled
into the vm that are needed.  If someone really wants to help me investigate
this, and I hope someone does, let me know and I can send you a Win32 VM or
the package to allow you to compile a vm on the platform of your choice.

Rob

----- Original Message -----
From: "Rob Withers" <[hidden email]>
To: "Paolo Bonzini" <[hidden email]>; <[hidden email]>;
"The general-purpose Squeak developers list"
<[hidden email]>
Sent: Tuesday, November 06, 2007 8:23 AM
Subject: Re: cyclic looping with [0 == object] whileFalse: [object :=
objectnextObject].


>
> ----- Original Message -----
> From: "Paolo Bonzini" <[hidden email]>
>
>> This would work for Rob however.
>>
>> Paolo
>>
>
> Hi Paolo,
>
> That would work for me in this situation, yes.  Also, I thought that
> Andreas' use of a marker to stop iteration would also work in this
> situation.  The issue is that I caused the situation by turning off
> ifTrue:
> inlining in the compiler (with help from others).
>
> This is just an intermediate step to where I really want to be, which is
> writing a macro which tests whether the receiver is Boolean, and if it is
> then run the inline form of ifTrue:, and if it is not then run the msg
> send
> form of ifTrue:.  This would avoid the above problem by keeping things
> inlined.  I have this new compound macro coded up, compiling and some
> basic
> tests and it works, but it makes my environment unstable.  I am getting
> the
> emergency evaluator or outright image crashes when using it.  It is
> driving
> me crazy, if I wasn't already.
>
> I am attching the Compiler package that I believe will load up for those
> who
> may be willing to help me figure this out.  After loading into a scratch
> image, run 'Compiler recompileAll'.  Then debug 'FileList open'.   This
> will
> show you one of the soft crashes (the emergency evaluator).  I suspect
> that
> I don't have things I need to do syntax highlighting in the debugger for
> the
> new macro code, but I am not sure if that is enough to cause crashes.  It
> does strange things like switch arguments, in this case a DirectoryEntry
> suddenly becomes 6.
>
> thanks for any assistance,
> Rob
>


--------------------------------------------------------------------------------


>
>