Sunday, October 30, 2011

Subtleties of Atomic Loading

Most of the time, atomic loading works like a charm.  Every once in a while, though, it gives you very confusing results.

I ran into one of these with the GemKit upgrade to VisualWorks 7.8.  I'd already determined that the package defined a compiler along with a class that used that compiler in one package.  That's a no-no.  I was getting into infinite loops that way.  I split the methods compiled by the new compiler into another package and that seemed to fix the problem.

The key phrase there is "seemed to".  I started finding that I was getting Message Not Understood errors by things that were supposed to be references to classes but were references to namespaces instead.  For example, code that read Core.Array was being compiled as if it was just Core.  I looked at how it was being compiled and it turned out that it was using the new compiler defined in the previous package.  The problem was that it wasn't supposed to use that compiler.  It was supposed to use the standard Smalltalk compiler.

As it turns out, there's code in the compilerClass method of the class that enables the special compiler on subclasses of this class, not on this class itself.  The code looked like this:

GBC.GbcHierarchyRoot class method:

compilerClass
 ^self  == GBC.GbcHierarchyRoot
  ifTrue: [super compilerClass]
  ifFalse: [GBC.GbcCompiler]

So, if the method being compiled is in GbcHierarchyRoot itself use the default compiler, otherwise, use the GbcCompiler for the subclass methods.

The problem here is that when you're doing atomic loading, at the time that this method is run, the class is in a different namespace than GBC.GbcHierarchyRoot. As such, the test was failing and using the GbcCompiler even for the methods in GbcHierarchyRoot itself.

The solution to this problem was to change the method as follows:
compilerClass

 ^name = #GbcHierarchyRoot
  ifTrue: [super compilerClass]
  ifFalse: [GBC.GbcCompiler]

Now the test works properly and it uses the default compiler class for GbcHierarchyRoot methods.  There were several methods that used this pattern, so I changed them all.

I'm making some progress but it's slow and complicated working out the interactions between atomic loading and the GemKit code. My goal is to keep the atomic analysis loader turned on all the time and still be able to load GemStone code from Store.  So far, I seem to be able to at least load the GemKit code.  The next step is to load actual GemStone code from Store.

1 comment:

  1. GbcManagement declares the compiler and is already separate from GS_ packages that are supposed to use the compiler. I'll update the class methods of GbcHierarchyRoot to compare the name as you have done.

    ReplyDelete