[Vm-dev] [COG] should cog unlinkSends in #flushMethodCacheFrom:to:

Eliot Miranda eliot.miranda at gmail.com
Fri Dec 31 18:25:08 UTC 2010

Hi Mariano,

On Fri, Dec 31, 2010 at 7:48 AM, Mariano Martinez Peck <
marianopeck at gmail.com> wrote:

> Hi Eliot. I am very newbie in all this stuff, so I would directly ask you
> if you could explain me my doubt ;)
> StackInterpreter >>  flushMethodCacheFrom: memStart to: memEnd
>     "Flush entries in the method cache only if the oop address is within
> the given memory range.
>     This reduces overagressive cache clearing. Note the AtCache is fully
> flushed, 70% of the time
>     cache entries live in newspace, new objects die young"
>     | probe |
>     probe := 0.
>     1 to: MethodCacheEntries do: [:i |
>             (methodCache at: probe + MethodCacheSelector) = 0
>                 ifFalse: [((((self oop: (methodCache at: probe +
> MethodCacheSelector) isGreaterThanOrEqualTo: memStart)
>                                         and: [self oop: (methodCache at:
> probe + MethodCacheSelector) isLessThan: memEnd])
>                                     or: [(self oop: (methodCache at: probe
> + MethodCacheClass) isGreaterThanOrEqualTo: memStart)
>                                             and: [self oop: (methodCache
> at: probe + MethodCacheClass) isLessThan: memEnd]])
>                                 or: [(self oop: (methodCache at: probe +
> MethodCacheMethod) isGreaterThanOrEqualTo: memStart)
>                                         and: [self oop: (methodCache at:
> probe + MethodCacheMethod) isLessThan: memEnd]])
>                         ifTrue: [methodCache at: probe +
> MethodCacheSelector put: 0]].
>             probe := probe + MethodCacheEntrySize].
>     1 to: AtCacheTotalSize do: [:i | atCache at: i put: 0]
> But if I see
> CoInterpreter >> flushMethodCache
>     "Flush the method cache. The method cache is flushed on every
> programming change and garbage collect."
>     1 to: MethodCacheSize do: [ :i | methodCache at: i put: 0 ].
>     lastMethodCacheProbeWrite := 0. "this for primitiveExternalMethod"
>     cogit unlinkAllSends
> So....my newbie question is just why the "cogit unlinkAllSends" is not need
> in Cog?   I mean, why cog doesn't need to do:
> CoInterpreter >>  flushMethodCacheFrom: memStart to: memEnd
>    super flushMethodCacheFrom: memStart to: memEnd .
>    self unlinkAllSends.

Good question.  The answer is that  flushMethodCacheFrom:to: is being used
to cheaply avoid having to remap entries in the method cache.  It gets
called from mapPointersInObjectsFrom:to: during GC (which moves objects) and
which could  actually remap the entries in the method cache instead of just
throwing them away.  The issue for remapping is that there is no ordering of
the objects in the method cache so one has to scan all of its entries, but
since its small that's not likely to be an issue.  In any case, throwing
away or unlinking sends in Cog is much more expensive, so I don't do it.

Instead, Cog object references are updated in mapInterpreterOops (also
called from mapPointersInObjectsFrom:to:) and high cost is avoided by
maintaining a flag, inFullGC, that tells Cog whether it has to remap all
object references or just young object references, and a list of Cog methods
containing young references (see selectors matching youngReferrers).  So
during a young space scavenge when doing mapMachineCode Cog only looks at
the methods containing young referrers, and typically there aren't any.


> Thanks for the explanation in advance,
> Mariano
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20101231/69b10823/attachment.htm

More information about the Vm-dev mailing list