On Sat, Apr 11, 2009 at 11:55 PM, John M McIntosh <johnmci@smalltalkconsulting.com> wrote:

Ok, I'm confused about the comments in initialCleanup, since in testing with a Pharo image from feb it DOES call the flushExternalPrimitives, but the comments imply a 3.8 or later image shouldn't have the root bit set.

Also then the flushExternalPrimitiveOf: seems to be invoked by the snapshotCleanUp.

So is the comment in initialCleanup wrong?

Could in the Closure VM could we skip flushExternalPrimitives for the new image type, since we *know* any closure image would have been processed by snapshotCleanUp, versus being a 3.2 image?

Good point.  So initialCleanup would then become

flushExternalPrimitives
self flushMethodCache.
self flushAtCache.
self flushExternalPrimitiveTable
 
initialCleanup
       "Images written by VMs earlier than 3.6/3.7 will wrongly have the root bit set on the active context. Besides clearing the root bit, we treat this as a marker that these images also lack a cleanup of external primitives (which has been introduced at the same time when the root bit problem was fixed). In this case, we merely flush them from here."

       ((self longAt: activeContext) bitAnd: RootBit) = 0 ifTrue:[^nil]. "root bit is clean"
       "Clean root bit of activeContext"
       self longAt: activeContext put: ((self longAt: activeContext) bitAnd: AllButRootBit).
       "Clean external primitives"
       self flushExternalPrimitives.


then


flushExternalPrimitives
       "Flush the references to external functions from plugin
       primitives. This will force a reload of those primitives when
       accessed next.
       Note: We must flush the method cache here so that any
       failed primitives are looked up again."
       | oop primIdx |
       oop := self firstObject.
       [self oop: oop isLessThan: endOfMemory]
               whileTrue: [(self isFreeObject: oop)
                               ifFalse: [(self isCompiledMethod: oop)
                                               ifTrue: ["This is a compiled method"
                                                       primIdx := self primitiveIndexOf: oop.
                                                       primIdx = PrimitiveExternalCallIndex
                                                               ifTrue: ["It's primitiveExternalCall"
                                                                       self flushExternalPrimitiveOf: oop]]].
                       oop := self objectAfter: oop].
       self flushMethodCache.
       self flushObsoleteIndexedPrimitives.
       self flushExternalPrimitiveTable


snapshotCleanUp
       "Clean up right before saving an image, sweeping memory and:
       * nilling out all fields of contexts above the stack pointer.
       * flushing external primitives
       * clearing the root bit of any object in the root table "
       | oop header fmt sz |
       oop := self firstObject.
       [self oop: oop isLessThan: endOfMemory]
               whileTrue: [(self isFreeObject: oop)
                               ifFalse: [header := self longAt: oop.
                                       fmt := header >> 8 bitAnd: 15.
                                       "Clean out context"
                                       (fmt = 3 and: [self isContextHeader: header])
                                               ifTrue: [sz := self sizeBitsOf: oop.
                                                       (self lastPointerOf: oop) + BytesPerWord
                                                               to: sz - BaseHeaderSize by: BytesPerWord
                                                               do: [:i | self longAt: oop + i put: nilObj]].
                                       "Clean out external functions"
                                       fmt >= 12
                                               ifTrue: ["This is a compiled method"
                                                       (self primitiveIndexOf: oop) = PrimitiveExternalCallIndex
                                                               ifTrue: ["It's primitiveExternalCall"
                                                                       self flushExternalPrimitiveOf: oop]]].
                       oop := self objectAfter: oop].
       self clearRootsTable


--
===========================================================================
John M. McIntosh <johnmci@smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================