<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]--></head><body>
GemStone does have weak references support.  One of my previous project called Iris2 had been using it for a long time.<div><br></div><div>You can asked Norm Green about the weak reference support.</div><div><br></div><div>Mang<br><br><br><a href="https://overview.mail.yahoo.com/?.src=iOS">Sent from Yahoo Mail for iPhone</a><br><br><p class="yahoo-quoted-begin" style="font-size: 15px; color: #715FFA; padding-top: 15px; margin-top: 0">On Friday, July 22, 2022, 9:44 AM, Otto Behrens via GemStone-Smalltalk <gemstone-smalltalk@lists.gemtalksystems.com> wrote:</p><blockquote class="iosymail"><div id="yiv6830374383"><div><div dir="ltr"><div class="yiv6830374383gmail_quote"><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex;" class="yiv6830374383gmail_quote"><div><div><div>We only see this happening after an MFC and only occasionally and also only from within gems that have been running before the MFC. <br clear="none"></div></div></div></blockquote><div><br clear="none"></div><div>Ok. We never run a full MFC with seaside sessions up. MFC works better if you can stop as many processes as possible. This is because it does a complete sweep of the repository. We rely on the Epoch GC to mark objects as possibly dead. There may be a subtle difference. The reclaim gem will come later and claim the space. This is my layman's understanding. I see you use oopIsDead when the space it occupies has not been reclaimed yet. I remember there may be some more complexity around the "deadness" of an object.</div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex;" class="yiv6830374383gmail_quote"><div><div><div></div><div>Since the oop lookup is part of rendering the log entries in our Seaside application, connected users can trigger this error. The stack trace I pasted was triggered multiple times from the same gem, while Seaside requests handled by other gems were processing the same data (i.e. log entries) without errors at the same time (probably getting a nil result for the objectForOop:, as expected).</div><div><br clear="none"></div></div><div>So, the error probably occurs at the first access to the instance variable of the object we retrieved via _objectForOop:. Since the place in the stack trace where the error is thrown is indeed the first time we access the instVar with the object that is reported missing, that is probably what is happening. Indeed.</div></div></blockquote><div><br clear="none"></div><div>I don't understand what you mean by "the instance variable of the object we retrieved via _objectForOop:". Are you saying that the object returned by _objectForOop: (which is now marked dead by the MFC) refers to another object, which may now also be possibly dead? Is it perhaps possible that your access modifies the object? I don't see the correlation: why accessing the instVar should have anything to do with it, unless there is a side effect on the accessing.</div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex;" class="yiv6830374383gmail_quote"><div><div>Unfortunately, I would expect _oopIsDead: to report the object as being dead in that case and thus not return us the object. </div></div></blockquote><div><br clear="none"></div><div>I agree, unless it is somehow re-attached. I think this is possible. Getting hold of an object that was marked as dead can somehow resurrect it, even if the gem that accessed it has the reference in transient memory. Perhaps this has something to do with it: there is a reference now (after looking at it) or the dead object was moved to a location meant for objects that are not dead.</div><div><br clear="none"></div><div>The block passed to ifNil:ifNotNil: in your code below could be a complex block, which means that there could be a copy of the invocation in memory that would now refer to "object".</div><div><br clear="none"></div><div>I'm not sure if #ifNil:ifNotNil: is optimised by the compiler in the version you are using. I know that there are some more optimisations in 3.6. There is an issue with calling </div><div><br clear="none"></div><div><div> (SystemRepository _oopIsDead: anInteger)</div><div><span style="white-space:pre-wrap;">                                                       </span>ifTrue: aBlock</div></div><div>because I think it cannot be optimised by the compiler (aBlock is sent to #ifTrue:ifFalse:), but if you do </div><div><div> (SystemRepository _oopIsDead: anInteger)</div><div><span style="white-space:pre-wrap;">                                                       </span>ifTrue: [ aBlock value ]</div></div><div>the ifTrue:ifFalse: call is optimised.</div><div><br clear="none"></div><div>This probably has nothing to do with your issue.</div><div><br clear="none"></div><div>Perhaps consider something like this. I know the multiple exit points are not as nice. But there is some logic to what the compiler can do.</div><div><br clear="none"></div><div><div>privateObjectAtUniqueIdentifier: anInteger ifAbsent: aBlock</div><div><span style="white-space:pre-wrap;"> | object |</span></div><div><span style="white-space:pre-wrap;">      </span>(object := Object _objectForOop: anInteger)</div><div><span style="white-space:pre-wrap;">             </span>ifNil: [ ^ aBlock value ].</div></div><div><span style="white-space:pre-wrap;">  ^ </span>(SystemRepository _oopIsDead: anInteger)<br clear="none"></div><div><span style="white-space:pre-wrap;">             ifTrue: [ aBlock value ]</span><br clear="none"></div><div><span style="white-space:pre-wrap;">               ifFalse: [ object ]</span></div><div><span style="white-space:pre-wrap;"><br clear="none"></span></div><div><span style="white-space:pre-wrap;">I wonder what will happen if you call _oopIsDead: first. Perhaps this will guard it from failing.</span></div><div><span style="white-space:pre-wrap;"><br clear="none"></span></div><div><span style="white-space:pre-wrap;">Just an old hacker trying things.</span></div><div id="yiv6830374383yqtfd87777" class="yiv6830374383yqt7378464838"><div><span style="white-space:pre-wrap;"><br clear="none"></span></div><div><span style="white-space:pre-wrap;">:-)</span></div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex;" class="yiv6830374383gmail_quote"><div><div>The implementation where we invoke _objectForOop: is shown below. First the version of the method as it was when the error occurred then the new version where I tried to the ‘fix’ it by wrapping the error handler around the entire code.</div><div><div><br clear="none"></div><div><div>privateObjectAtUniqueIdentifier: anInteger ifAbsent: aBlock</div><div><span style="white-space:pre-wrap;">      </span>^ (Object _objectForOop: anInteger)</div><div><span style="white-space:pre-wrap;">             </span>ifNil: aBlock</div><div><span style="white-space:pre-wrap;">           </span>ifNotNil:[ :object | [ (SystemRepository _oopIsDead: anInteger)</div><div><span style="white-space:pre-wrap;">                                                 </span>ifTrue: aBlock</div><div><span style="white-space:pre-wrap;">                                                  </span>ifFalse: [ object ] ] on: Error do: [:e | aBlock value ] ]</div><div><br clear="none"></div><div><br clear="none"></div><div><div>privateObjectAtUniqueIdentifier: anInteger ifAbsent: aBlock</div><div><span style="white-space:pre-wrap;"> </span>^ [ (Object _objectForOop: anInteger)</div><div><span style="white-space:pre-wrap;">           </span>ifNil: aBlock</div><div><span style="white-space:pre-wrap;">           </span>ifNotNil:[ :object | (SystemRepository _oopIsDead: anInteger)</div><div><span style="white-space:pre-wrap;">                                                   </span>ifTrue: aBlock</div><div><span style="white-space:pre-wrap;">                                                  </span>ifFalse: [ object ] ] </div><div><span style="white-space:pre-wrap;">             </span>] on: Error do: [:e | </div><div><span style="white-space:pre-wrap;">                     </span>"oop fishing in GemStone may return internal objects that do not implement ifNil:ifNotNil:.</div><div><span style="white-space:pre-wrap;">                        </span>_oopIsDead can also error (see method comment). </div><div><span style="white-space:pre-wrap;">                   </span>capture these objects here and return nil"</div><div><span style="white-space:pre-wrap;">                 </span>aBlock value ]</div></div></div></div></div>_______________________________________________<br clear="none">
GemStone-Smalltalk mailing list<br clear="none">
<a rel="nofollow noopener noreferrer" shape="rect" ymailto="mailto:GemStone-Smalltalk@lists.gemtalksystems.com" target="_blank" href="mailto:GemStone-Smalltalk@lists.gemtalksystems.com">GemStone-Smalltalk@lists.gemtalksystems.com</a><br clear="none">
<a rel="nofollow noopener noreferrer" shape="rect" target="_blank" href="https://lists.gemtalksystems.com/mailman/listinfo/gemstone-smalltalk">https://lists.gemtalksystems.com/mailman/listinfo/gemstone-smalltalk</a><br clear="none">
</blockquote></div></div></div><div id="yiv6830374383yqtfd77604" class="yiv6830374383yqt7378464838">
</div></div></div><div class="yqt7378464838" id="yqtfd03311">_______________________________________________<br clear="none">GemStone-Smalltalk mailing list<br clear="none"><a shape="rect" ymailto="mailto:GemStone-Smalltalk@lists.gemtalksystems.com" href="mailto:GemStone-Smalltalk@lists.gemtalksystems.com">GemStone-Smalltalk@lists.gemtalksystems.com</a><br clear="none"><a shape="rect" href="https://lists.gemtalksystems.com/mailman/listinfo/gemstone-smalltalk" target="_blank">https://lists.gemtalksystems.com/mailman/listinfo/gemstone-smalltalk</a><br clear="none"></div><blockquote></blockquote></blockquote></div>
</body></html>