Am 30.08.2019 18:05:10 schrieb Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:
Hi,Some CompiledMethod might be replaced in their respective MethodDictionary (recompiled), but persist in the system when they have some block referenced.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 crash.I thought I could track such case down with this snippet:(CompiledBlock allInstances reject: [:e | e isClean or: [each home method isInstalled]]) inspect.or:(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>>migrateMost 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.