[squeak-dev] Emergency evaluator on update: Environments?

Bert Freudenberg bert at freudenbergs.de
Mon May 27 12:05:06 UTC 2013


On 2013-05-27, at 00:47, Levente Uzonyi <leves at elte.hu> wrote:

> On Sun, 26 May 2013, Frank Shearar wrote:
> 
>> I'm not sure what caused it, but I just hit an emergency evaluator on
>> updating a clean 4.5 (as in the Squeak4.5.image in the build scripts).
>> 
>> It goes something like this:
>> 
>> ***System error handling failed***
>> Original error: MessageNotUnderstood: UndefinedObject>>at:ifPresent:.
>>   Debugger error: MessageNotUnderstood: UndefinedObject>>at:ifPresent::
>> Debugger class(Object)>>primitiveError:
>> [] in [] in Debugger class>>morphicOpenOn:context:label:contents:fullView:
>> BlockContext>>cull:
>> [] in MethodContext(ContextPart)>>handleSignal:
>> BlockClosure>>ensure:
>> MethodContext(ContextPart)>>handleSignal:
>> MessageNotUnderstood(Exception)>>signal
>> UndefinedObject(Object)>>doesNotUnderstand: #at:ifPresent:
>> Environment>>at:ifPresentAndInMemory:
>> SmalltalkImage>>at:ifPresentAndInMemory:
>> Debugger>>process:controller:context:
>> [] in [] in Debugger class>>morphicOpenOn:context:label:contents:fullView:
>> 
>> and so on. I'm strongly tempted to point at Environments-cwp.27
>> because of that call to #at:ifPresentAndInMemory: which uses
>> Environment's contents ivar prior to this change and the new
>> declarations ivar after. A missing migration step over the shape
>> change?
> 
> I think the cause of the problem is that MC doesn't have atomic loading. I guess the variables are renamed first in the class, but that triggers recompilation of all existing methods, which will point to nonexistent variables.
> 
> If I'm right, then there needs to be an intermediate step, where the old and the new variables coexist and both point to the same objects.
> 
> So, I'd probably use 3 updates (and create 2 update maps, one after all but the last point):
> 1. Add the new variables to the class, and a migration method that assigns the value of the old variables to the new ones.
> 2. In the preamble send the migration method to all Environment instances. Then update all methods to use only the new variables
> 3. Remove the old variables
> 
> 
> Levente


I wonder if this could be generalized?

The variable adding/removing part of it could be handled by MC. That is, new variables would be added in MCClassDefinition>>load and old variables be removed in MCClassDefinition>>postLoad.

Not sure about the migration methods. It is similar to the existing hierarchy of #convertToCurrentVersion:refStream: methods, but would be dealing with live instances. Perhaps one would need to override #newInstanceFrom:variable:size:map:? That is dangerous, however, because it's from the inner workings of class mutation and cannot easily be tested. 

The only thing I can imagine working would be to make instance variable renames be an explicit action (invoked from a menu perhaps) that would first generate the conversion method and then do the class mutation, which would use that conversion method to assign old inst var contents to the new inst var. Currently, new inst vars are always nil, and old inst vars lost. Are there other Smalltalks that handle this?

- Bert -




More information about the Squeak-dev mailing list