Mantis Bugtracker
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0006667 [Squeak] VM major always 09-12-07 00:23 04-18-10 22:07
Reporter tim View Status public  
Assigned To tim
Priority normal Resolution fixed  
Status closed   Product Version 3.9
Summary 0006667: biasToGrow code typo
Description In an email from jan 23 07, JMM explained a discovered bug in biasToGrow that causes an interesting problem.
Additional Information 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 [^]
========================================================================
===
Attached Files  JMM-fixBiasToGrow.1.cs.zip [^] (756 bytes) 09-12-07 00:24

- Relationships

SYSTEM WARNING: Creating default object from empty value

related to 0004709closed  VM blocks after memory consumtion exceeds ~120MB 
child of 0006671closed tim Build VMMaker for 3.9 

- Notes
(0011135 - 25 - 25 - 25 - 25 - 25 - 25)
tim
09-17-07 20:25

Installed; VMMaker-tpr.63
 

- Issue History
Date Modified Username Field Change
09-12-07 00:23 tim New Issue
09-12-07 00:23 tim Status new => assigned
09-12-07 00:23 tim Assigned To  => tim
09-12-07 00:23 tim Relationship added related to 0004709
09-12-07 00:24 tim File Added: JMM-fixBiasToGrow.1.cs.zip
09-12-07 01:15 lewis Issue Monitored: lewis
09-14-07 00:01 tim Relationship added child of 0006671
09-17-07 20:25 tim Note Added: 0011135
09-17-07 20:25 tim Status assigned => resolved
09-17-07 20:25 tim Resolution open => fixed
04-18-10 22:07 andreas Status resolved => closed


Mantis 1.0.8[^]
Copyright © 2000 - 2007 Mantis Group
53 total queries executed.
37 unique queries executed.
Powered by Mantis Bugtracker