<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 8, 2016 at 2:57 PM, Bert Freudenberg <span dir="ltr"><<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div style="word-wrap:break-word">On 08.04.2016, at 20:00, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>> wrote:<br><div><blockquote type="cite"><br><div><div dir="ltr"><div class="gmail_extra">On Fri, Apr 8, 2016 at 9:29 AM, Levente Uzonyi <span dir="ltr"><<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">So I suggest we should use both changes if it has no negative side effects. Eliot? :)<br></blockquote><div><br></div><div>+1. I had hoped that scavenging would be run automatically, but this won't happen with huge allocations. For small allocations, when eden is full, the machine code new primitive will set the "needs scavenge" flag, when <span style="font-size:12.8px">#handleFailingBasicNew: runs the scavenger will run, and so there is no need to do </span>Smalltalk garbageCollectMost, because that has happened implicitly. But for huge allocations I think the code doesn't set the scavenge flag, it merely fails the primitive. But I need to check this.</div><div><br></div><div>What do we prefer, having the machine code for new always set the "needs scavenge" flag if an allocation failed because there was no room, or have <span style="font-size:12.8px">#handleFailingBasicNew: et al calls </span>Smalltalk garbageCollectMost explicitly? </div></div></div></div></div></blockquote><div><br></div><div>IMHO there’s no advantage to rely on the image to do that. I’d prefer handling it in the VM.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>When I saw Bert's message above, denying that basicNew: ever fails, I immediately repeated Bert's experiment, /knowing/ that basicNew /does/ fail. But to my surprise my experiment revealed Bert's result, that basicNew does not appear to fail :-). </div></div></div></div></div></blockquote><div><br></div><div>Now that’s a relief ;)</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Of course the gotcher is that the backward branch in the loop over allocation checks for events, and runs the scavenger, so a simple loop never shows failures. It's difficult to make it fail, but fail it will :-)<br></div></div></div></div></div></blockquote><br></div><div>Yeah. So more smaller allocations will not make it fail, but few bigger ones does.</div></div></blockquote><div><br></div><div>Right.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div>When exactly is a full GC triggered in the current scheme?<br></div></div></blockquote><div><br></div><div>When handleFailingBasicNew: fails to allocate. Here's the code:</div><div><br></div><div>Behavior>>basicNew</div><div><span class="" style="white-space:pre">        </span>"Primitive. Answer an instance of the receiver (which is a class) with no </div><div><span class="" style="white-space:pre">        </span> indexable variables. Fail if the class is indexable. Essential. See Object </div><div><span class="" style="white-space:pre">        </span> documentation whatIsAPrimitive.</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span> If the primitive fails because space is low then the scavenger will run</div><div><span class="" style="white-space:pre">        </span> before the method is activated. Check that space was low and retry</div><div><span class="" style="white-space:pre">        </span> via handleFailingBasicNew if so."</div><div><br></div><div><span class="" style="white-space:pre">        </span><primitive: 70 error: ec></div><div><span class="" style="white-space:pre">        </span>ec == #'insufficient object memory' ifTrue:</div><div><span class="" style="white-space:pre">                </span>[^self handleFailingBasicNew].</div><div><span class="" style="white-space:pre">        </span>self isVariable ifTrue: [^self basicNew: 0].</div><div><span class="" style="white-space:pre">        </span>self primitiveFailed</div><div><br></div><div>handleFailingBasicNew</div><div><span class="" style="white-space:pre">        </span>"handleFailingBasicNew gets sent after basicNew has failed and allowed</div><div><span class="" style="white-space:pre">        </span> a scavenging garbage collection to occur. The scavenging collection</div><div><span class="" style="white-space:pre">        </span> will have happened as the VM is activating the (failing) basicNew. If</div><div><span class="" style="white-space:pre">        </span> handleFailingBasicNew fails then the scavenge failed to reclaim sufficient</div><div><span class="" style="white-space:pre">        </span> space and a global garbage collection is required. Retry after garbage</div><div><span class="" style="white-space:pre">        </span> collecting and growing memory if necessary.</div><div><br></div><div><span class="" style="white-space:pre">        </span> Primitive. Answer an instance of this class with the number of indexable</div><div><span class="" style="white-space:pre">        </span> variables specified by the argument, sizeRequested. Fail if this class is not</div><div><span class="" style="white-space:pre">        </span> indexable or if the argument is not a positive Integer, or if there is not</div><div><span class="" style="white-space:pre">        </span> enough memory available. Essential. See Object documentation whatIsAPrimitive."</div><div><br></div><div><span class="" style="white-space:pre">        </span><primitive: 70></div><div><span class="" style="white-space:pre">        </span>Smalltalk garbageCollect < 1048576 ifTrue:</div><div><span class="" style="white-space:pre">                </span>[Smalltalk growMemoryByAtLeast: 1048576].</div><div><span class="" style="white-space:pre">        </span>^self handleFailingFailingBasicNew "retry after global garbage collect"</div><div><br></div><div><div>handleFailingFailingBasicNew</div><div><span class="" style="white-space:pre">        </span>"This basicNew gets sent after handleFailingBasicNew: has done a full</div><div><span class="" style="white-space:pre">        </span> garbage collection and possibly grown memory. If this basicNew fails</div><div><span class="" style="white-space:pre">        </span> then the system really is low on space, so raise the OutOfMemory signal.</div><div><br></div><div><span class="" style="white-space:pre">        </span> Primitive. Answer an instance of this class with the number of indexable</div><div><span class="" style="white-space:pre">        </span> variables specified by the argument, sizeRequested. Fail if this class is not</div><div><span class="" style="white-space:pre">        </span> indexable or if the argument is not a positive Integer, or if there is not</div><div><span class="" style="white-space:pre">        </span> enough memory available. Essential. See Object documentation whatIsAPrimitive."</div><div><br></div><div><span class="" style="white-space:pre">        </span><primitive: 70></div><div><span class="" style="white-space:pre">        </span>"space must be low"</div><div><span class="" style="white-space:pre">        </span>OutOfMemory signal.</div><div><span class="" style="white-space:pre">        </span>^self basicNew "retry if user proceeds"</div></div><div><br></div><div>So if one does SomeClass basicNew and this fails with the error code #'insufficient object memory' it did so because the VM is (at least temporarily) out of memory. If the primitive invoked by basicNew sets the "scavengeNeeded" flag, then by the time we get to the "^self handleFailingBasicNew" send in basicNew, the scavenger will have run, because events are responded to when a method builds a frame, which basicNew does as it fails. So basicNew sends handleFailingBasicNew to retry the allocation, assuming the scavenger has run.</div><div><br></div><div>So if handleFailingBasicNew fails it means there's not enough room in newSpace or in oldSpace. Therefore it runs Smalltalk garbageCollect to reclaim space in oldSpace, and then invokes handleFailingFailingBasicNew to retry the allocation a third time. If handleFailingFailingBasicNew it means we're really out of space and so it raises the OutOfMemory exception.</div><div><br></div><div>The code is similar for basicNew:.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div>
- Bert -<br><br><br>
</div>
<br></div><br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>