[squeak-dev] out-of-date CompiledMethod

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Aug 30 16:04:51 UTC 2019

Some CompiledMethod might be replaced in their respective MethodDictionary
(recompiled), but persist in the system when they have some block

We can track them down with this snippet:

     (CompiledMethod allInstances reject: #isInstalled) inspect.

Most of the time, it's innocuous, but if the method were recompiled due to
a change of class layout and if the block access inst. var. slots that
since moved, all sort of undefined behavior can happen, including a VM

I thought I could track such case down with this snippet:

    (CompiledBlock allInstances reject: [:e | e isClean or: [each home
method isInstalled]]) inspect.


    (BlockContext allInstances reject: [:e | e closure isClean or: [each
home method isInstalled]]) inspect.

But both BlockContext and CompiledBlock allInstances isEmpty. Ah yes,
CompiledBlock is future for Sista, and now we only get Context in Spur...

    (Context allSubInstances reject: [:e | e methods isInstalled]) inspect.

gives a longer list than the first snippet, because the out-of-date method
might be used in many different context...

However, I can't find those having dangerous (not clean) blocks:

    (Context allSubInstances reject: [:e | e closure isNil]) inspect.
    (Context allSubInstances reject: [:e | e closure isNil or: [e closure
isClean]]) inspect.
    (Context allSubInstances reject: [:e | e closure isNil or: [e closure
isClean or: [e method isInstalled]]]) inspect.

The first two lists are not empty, but the last one is empty. So that's
still  not the right invocation: there is no active Context for those
closure, so here is a better snippet:

    (BlockClosure allSubInstances reject: [:e | e outerContext method
isInstalled or: [e isClean]]) inspect.

In a VMMaker image built from latest squeak distribution, the out-of-date
CompiledMethods given by the first snippet is below:

(WorldMenuProvider>>#preferencesBrowser "a CompiledMethod(3800333)") .
(WorldMenuProvider>>#nextWindow "a CompiledMethod(1345923)") .
(WorldMenuProvider>>#closeTopWindow "a CompiledMethod(1052691)") .
(WorldMenuProvider>>#helpOnServices "a CompiledMethod(1013869)") .
(WorldMenuProvider>>#rebuildRegistry "a CompiledMethod(2839737)") .
(WorldMenuProvider>>#servicesBrowser "a CompiledMethod(485047)") .
(WorldMenuProvider>>#createNewService "a CompiledMethod(2658559)") .
(WorldState>>#stepListSortBlock "a CompiledMethod(491105)") .
(ServiceAction class>>#id:text:button:description:action: "a
CompiledMethod(3812069)") .
(ServiceAction class>>#text:button:description:action: "a
CompiledMethod(1460587)") .
(ServiceCategory class>>#text:button:description: "a
CompiledMethod(3025003)") .
(ServiceShortcuts class>>#insertPrefShortcut: "a CompiledMethod(2077141)") .
(WeakRegistry>>#installFinalizer "a CompiledMethod(1322897)") .
(PluggableDictionary class>>#integerDictionary "a CompiledMethod(353359)") .
(Slider>>#computeSlider "a CompiledMethod(682213)") .
(MorphicAlarmQueue>>#migrate "a CompiledMethod(1994485)") .
(SqueakReleaseNotes class>>#asHelpTopic "a CompiledMethod(79489)") .
(SqueakTheme class>>#addToolColors: "a CompiledMethod(1225541)") .

+ a bunch of DoIt's for which I can't find the pointers (referenced by
nothing, can it be a memory leak from VM?).

By using 'chase pointers' menu, or the second snippet to catch Context,
most come from ServiceRegistry.
There are also special sortBlock for Heap (stepListSortBlock from
WorldState>>initialize and also WorldState alarms) or hashBlock
(integerDictionary from Unicode ToUpper).
The HostWindowProxy registry has the obsolete installFinalizer.

And the unclean closure given by latest snippet are very few (copy omitted):

[closure] in WorldMenuProvider>>helpOnServices
[closure] in ServiceShortcuts class>>insertPrefShortcut:
[closure] in WeakRegistry>>installFinalizer
[closure] in MorphicAlarmQueue>>migrate

Most are not clean because they close over self or a method argument.
The only potentially problematic is the one closing over an inst. var.
(more over for writing!) WeakRegistry>>installFinalizer.
It would be safer to transform this closure to just send a message rather
than messing directly with the ivar...

It's not a problem right now until we change WeakRegistry layout, but I
wanted to share these findings, since that's the kind of tricky things we
must care of when releasing a new version.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20190830/62fd85b2/attachment.html>

More information about the Squeak-dev mailing list