[Vm-dev] Root bit on active context? Closure VMs and thoughts on flushExternalPrimitives.

John M McIntosh johnmci at smalltalkconsulting.com
Sun Apr 12 06:55:21 UTC 2009


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?



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 at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
= 
= 
= 
========================================================================





More information about the Vm-dev mailing list