On 05.08.2009, at 12:08, Stéphane Ducasse wrote:

>> I did that in pharo 211 and it worked.
>>>
>> Yes, that was before closures.
>>
>>>     MethodContext allInstances size 2309
>>>
>>
>> with the blockClosures, creation of method contexts happes far more
>> frequently than it used to.
>> (as both closures and methods use the same context objects)
>>
>> It of course could be a sign that it happens actually too much.
>
> I stopped in the image that did not crash yet at a couple of  
> billions :)
>

Yes, but not "too much" in this sense. When creating new instances  
while counting
them, the case "no problem" and "endless loop" are very close  
together... a very
tiny increase, or even just a change in context-creation behavior  
could trigger
the case that it creates too many contexts.

This is one possbility: the change in creation pattern cause the  
problem, nothing
to worry about.

So let see.

It used to be that block-context where created by sending blockCopy:  
to thiscontext:

13 <89> pushThisContext:
14 <75> pushConstant: 0
15 <C8> send: blockCopy:
16 <A4 02> jumpTo: 20
18 <73> pushConstant: nil
19 <7D> blockReturn
20 <87> pop
21 <78> returnSelf

Now, the same code reads like this:

13 <8F 00 00 02> closureNumCopied: 0 numArgs: 0 bytes 17 to 18
17      <73> pushConstant: nil
18      <7D> blockReturn
19 <87> pop
20 <78> returnSelf


and the closureNumCopied bytecode creates a BlockClosure object which  
is *not* the
context. The context is later created when evaluating the Closure.

So the time *when* an allocation of a new context may happen changed  
fundamtally.

If we now look at the code for getting allinstances:

allInstances
        "Answer a collection of all current instances of the receiver."

        | all |
        all := OrderedCollection new.
        self allInstancesDo: [:x | x == all ifFalse: [all add: x]].
        ^ all asArray

(allInstancesDo: is carefully written to not use any real blocks, just  
inlined ones).

So the context for the block was created just once, before calling  
#llInstancesDo:
Bytecode:

29 <40> pushLit: OrderedCollection
30 <CC> send: new
31 <68> popIntoTemp: 0
32 <70> self
33 <89> pushThisContext:
34 <76> pushConstant: 1
35 <C8> send: blockCopy:
36 <A4 0B> jumpTo: 49
.... and so on.

Now with the Closures, it evaluates the closure in allInstancesDo:,  
leading for the
closure VM to a potential allocation of a context in the execution of  
allInstancesDo:
(and for each eval, it´s a loop). So we now have potentiall  
allocations of new instances
of methodcontext when iterating over the existing ones. --> race  
condition.

        Marcus



--
Marcus Denker - http://marcusdenker.de
PLEIAD Lab - Computer Science Department (DCC) - University of Chile


_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to