<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">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</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 &lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt; 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">&lt;<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>&gt;</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&#39;t happen with huge allocations.  For small allocations, when eden is full, the machine code new primitive will set the &quot;needs scavenge&quot; 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&#39;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 &quot;needs scavenge&quot; 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&#39;s message above, denying that basicNew: ever fails, I immediately repeated Bert&#39;s experiment, /knowing/ that basicNew /does/ fail.  But to my surprise my experiment revealed Bert&#39;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&#39;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&#39;s the code:</div><div><br></div><div>Behavior&gt;&gt;basicNew</div><div><span class="" style="white-space:pre">        </span>&quot;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.&quot;</div><div><br></div><div><span class="" style="white-space:pre">        </span>&lt;primitive: 70 error: ec&gt;</div><div><span class="" style="white-space:pre">        </span>ec == #&#39;insufficient object memory&#39; 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>&quot;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.&quot;</div><div><br></div><div><span class="" style="white-space:pre">        </span>&lt;primitive: 70&gt;</div><div><span class="" style="white-space:pre">        </span>Smalltalk garbageCollect &lt; 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 &quot;retry after global garbage collect&quot;</div><div><br></div><div><div>handleFailingFailingBasicNew</div><div><span class="" style="white-space:pre">        </span>&quot;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.&quot;</div><div><br></div><div><span class="" style="white-space:pre">        </span>&lt;primitive: 70&gt;</div><div><span class="" style="white-space:pre">        </span>&quot;space must be low&quot;</div><div><span class="" style="white-space:pre">        </span>OutOfMemory signal.</div><div><span class="" style="white-space:pre">        </span>^self basicNew  &quot;retry if user proceeds&quot;</div></div><div><br></div><div>So if one does SomeClass basicNew and this fails with the error code #&#39;insufficient object memory&#39; it did so because the VM is (at least temporarily) out of memory.  If the primitive invoked by basicNew sets the &quot;scavengeNeeded&quot; flag, then by the time we get to the &quot;^self handleFailingBasicNew&quot; 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&#39;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&#39;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>