An issue with Slang, the interpreter & the VM, and a period in biasToGrow.

John M McIntosh johnmci at smalltalkconsulting.com
Tue Jan 23 05:15:06 UTC 2007


I was chasing a problem with Sophie where the VM would suddenly grow  
by 800MB. In looking I discovered a problem with how Slang interprets
the following code.

Background: When an incremental garbage collection is done and the  
free space is less than the grow head room and the bias to grow is  
turned on,
then we call biasToGrow.  I'll note normally the gcBiasToGrow would  
be false unless you turn it on so few users have seen this problem.

The problem is that Slang converts the "growSize :=  growHeadroom*3/2  
- (self sizeOfFree: freeBlock)" to nothing. In the past I know this
worked because I had worked on choosing the magic 3/2 number.

ObjectMemory>>incrementalGC

...

			(((self sizeOfFree: freeBlock) < growHeadroom) and:
				[gcBiasToGrow > 0])
				ifTrue: [self biasToGrow.
						weDidGrow := true].
			youngStart := freeBlock].

...


ObjectMemory>>biasToGrow
	| growSize |
	growSize :=  growHeadroom*3/2 - (self sizeOfFree: freeBlock)
	self growObjectMemory: growSize



ObjectMemory>>growObjectMemory: delta
	"Attempt to grow the object memory by the given delta
	amount "
	| limit |
	statGrowMemory := statGrowMemory + 1.
	limit := self sqGrowMemory: memoryLimit By: delta.
	limit = memoryLimit
		ifFalse: [memoryLimit := limit - 24.
			"remove a tad for safety"
			self initializeMemoryFirstFree: freeBlock]


---------------------------------------------------

But the C code that Slang generates looks like so:


		if ((((longAt(foo->freeBlock)) & AllButTypeMask) < foo- 
 >growHeadroom) && (foo->gcBiasToGrow > 0)) {
			/* begin biasToGrow */
			/* begin growObjectMemory: */
			foo->statGrowMemory += 1;
			limit = sqGrowMemoryBy(foo->memoryLimit, growSize);
			if (!(limit == foo->memoryLimit)) {
				foo->memoryLimit = limit - 24;
				initializeMemoryFirstFree(foo->freeBlock);
			}
			weDidGrow = 1;
		}

The C compiler is happy (mostly) and depending on what it sticks in  
the growSize memory location, perhaps it's perhaps zero, perhaps not,  
we might as I did some odd behaviour.

How clever, and if you've come this far, you've like seen the missing  
period. at the end of
	"growSize :=  growHeadroom*3/2 - (self sizeOfFree: freeBlock)"

Helpfully Slang doesn't complaint about the missing period and forges  
onward creating in-valid C code, without the proper meaning.
Hopefully people writing Slang code are muttering, gee I wonder if I  
have some code that isn't quite what I think it is?


With the period of course the code becomes

		if ((((longAt(foo->freeBlock)) & AllButTypeMask) < foo- 
 >growHeadroom) && (foo->gcBiasToGrow > 0)) {
			/* begin biasToGrow */
			growSize = (((sqInt) (foo->growHeadroom * 3) >> 1)) - ((longAt(foo- 
 >freeBlock)) & AllButTypeMask);
			/* begin growObjectMemory: */
			foo->statGrowMemory += 1;
			limit = sqGrowMemoryBy(foo->memoryLimit, growSize);
			if (!(limit == foo->memoryLimit)) {
				foo->memoryLimit = limit - 24;
				initializeMemoryFirstFree(foo->freeBlock);
			}
			weDidGrow = 1;
		}

Mostly likely in working with Tim I managed to copy/paste some code  
and missed the '.'

Lastly I'll note the biasToGrow logic is there because there is a  
problem when Squeak reaches the boundary point where it must decide  
to grow, before doing that it does an incremental GC, the issue is  
that if the incremental GC can recover just enough few bytes the grow  
will not happen, but we will do another GC really really soon, thus  
you see Squeak at 100% CPU in the GC logic, yet not quite growing, at  
some point you will go over the boundary and grow, solving the problem.

The bias to grow logic then ensures the VM will grow in increments up  
to a certain threshold before forcing a full GC, thus avoids the  
particular problem.

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





More information about the Squeak-dev mailing list