<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Oct 21, 2013 at 12:25 AM, Frank Shearar <span dir="ltr">&lt;<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
<br>
On 21 Oct 2013, at 8:18, <a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a> wrote:<br>
<br>
&gt;<br>
&gt; Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>
&gt; <a href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.469.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.469.mcz</a><br>
&gt;<br>
&gt; ==================== Summary ====================<br>
&gt;<br>
&gt; Name: VMMaker.oscog-eem.469<br>
&gt; Author: eem<br>
&gt; Time: 20 October 2013, 5:15:49.893 pm<br>
&gt; UUID: 9a1b817f-2cee-487a-8c07-6444e28a16aa<br>
&gt; Ancestors: VMMaker.oscog-eem.468<br>
&gt;<br>
&gt; Rethink the sorting of free space for exact-fit compact post global<br>
&gt; GC.  Since the sweep to free unmarked objects is linear through old<br>
&gt; space it can also sort free space.  So<br>
&gt; freeUnmarkedObjectsAndNilUnmarkedWeaklingSlots =&gt;<br>
&gt; freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoallesceFreeSpace (glup ;-) ).<br>
&gt;<br>
<br>
</div>At the risk of being a pain, you need to coalesce the two l&#39;s in &#39;coallesce&#39;.<br></blockquote><div><br></div><div>Phew, thanks!  Now freeUnmarkedObjectsNilUnmarkedWeaklingSlotsAndSortAndCoalesceFreeSpace is one character shorter ;-).</div>
<div><br></div><div>This is the complete opposite of a pain.  Thank you both, Frank and Henry!</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
frank<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
&gt; Make sure that bridges are marked so they won&#39;t be freed in<br>
&gt; fUONUWASACFS.<br>
&gt;<br>
&gt; Add freeChunkPrevIndex to link next nodes to their precedessors<br>
&gt; so that free chunks can be quickly removed during coallescing.<br>
&gt;<br>
&gt; Implement an iterative freeTreeNodesDo: so that Slang can inline the<br>
&gt; block arguments to it.<br>
&gt;<br>
&gt; Refactor the code that removes a tree node in<br>
&gt; allocateOldSpaceChunkOfBytes: et al, out into<br>
&gt; unlinkSolitaryFreeTreeNode:<br>
&gt;<br>
&gt; Still have to reverse small list heads post-sweep and account for free space properly.<br>
&gt;<br>
&gt; =============== Diff against VMMaker.oscog-eem.468 ===============<br>
&gt;<br>
&gt; Item was added:<br>
&gt; + ----- Method: Spur32BitMemoryManager&gt;&gt;coallesce:and: (in category &#39;gc - global&#39;) -----<br>
&gt; + coallesce: obj1 and: obj2<br>
&gt; +    | header1NumSlots header2NumSlots obj2slots newNumSlots |<br>
&gt; +    header1NumSlots := self rawNumSlotsOf: obj1.<br>
&gt; +    header2NumSlots := self rawNumSlotsOf: obj2.<br>
&gt; +<br>
&gt; +    &quot;compute total number of slots in obj2, including header&quot;<br>
&gt; +    obj2slots := header2NumSlots = self numSlotsMask<br>
&gt; +                    ifTrue: [(self longAt: obj2 - self baseHeaderSize) + (2 * self baseHeaderSize / self wordSize)]<br>
&gt; +                    ifFalse: [(header2NumSlots = 0 ifTrue: [1] ifFalse: [header2NumSlots]) + (self baseHeaderSize / self wordSize)].<br>
&gt; +    obj2slots := obj2slots + (obj2slots bitAnd: 1).<br>
&gt; +    self assert: obj2slots * self wordSize = (self bytesInObject: obj2).<br>
&gt; +<br>
&gt; +    &quot;if obj1 already has a double header things are simple...&quot;<br>
&gt; +    header1NumSlots = self numSlotsMask ifTrue:<br>
&gt; +        [self longAt: obj1  - self baseHeaderSize put: obj2slots + (self longAt: obj1 - self baseHeaderSize).<br>
&gt; +         ^obj1].<br>
&gt; +<br>
&gt; +    &quot;compute total number of slots in obj1, excluding header&quot;<br>
&gt; +    header1NumSlots := header1NumSlots = 0<br>
&gt; +                            ifTrue: [2]<br>
&gt; +                            ifFalse: [header1NumSlots + (header1NumSlots bitAnd: 1)].<br>
&gt; +    self assert: header1NumSlots * self wordSize + self baseHeaderSize = (self bytesInObject: obj1).<br>
&gt; +    newNumSlots := obj2slots + header1NumSlots.<br>
&gt; +<br>
&gt; +    &quot;if obj1 still only requires a single header things are simple...&quot;<br>
&gt; +    newNumSlots &lt; self numSlotsMask ifTrue:<br>
&gt; +        [self byteAt: obj1 + (self numSlotsFullShift / BitsPerByte)<br>
&gt; +            put: newNumSlots.<br>
&gt; +         ^obj1].<br>
&gt; +<br>
&gt; +    &quot;convert from single to double header...&quot;<br>
&gt; +    newNumSlots := newNumSlots - (self baseHeaderSize / self wordSize).<br>
&gt; +    self longAt: obj1 + self baseHeaderSize<br>
&gt; +            put: (self longAt: obj1);<br>
&gt; +        longAt: obj1 + 4 + self baseHeaderSize<br>
&gt; +            put: ((self longAt: obj1 + 4) bitOr: self numSlotsMask &lt;&lt; self numSlotsHalfShift).<br>
&gt; +    self longAt: obj1<br>
&gt; +            put: newNumSlots.<br>
&gt; +    self longAt: obj1 + 4<br>
&gt; +            put: self numSlotsMask &lt;&lt; self numSlotsHalfShift.<br>
&gt; +    ^obj1 + self baseHeaderSize!<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Spur32BitMemoryManager&gt;&gt;initSegmentBridgeWithBytes:at: (in category &#39;segments&#39;) -----<br>
&gt;  initSegmentBridgeWithBytes: numBytes at: address<br>
&gt;      &lt;var: #numBytes type: #usqLong&gt;<br>
&gt;      | numSlots |<br>
&gt;      &quot;must have room for a double header&quot;<br>
&gt;      self assert: (numBytes \\ self allocationUnit = 0<br>
&gt;                   and: [numBytes &gt;= (self baseHeaderSize + self baseHeaderSize)]).<br>
&gt;      self flag: #endianness.<br>
&gt;      numSlots := numBytes - self baseHeaderSize - self baseHeaderSize &gt;&gt; self shiftForWord.<br>
&gt;      self longAt: address put: numSlots;<br>
&gt;          longAt: address + 4 put: self numSlotsMask &lt;&lt; self numSlotsHalfShift;<br>
&gt;          longAt: address + 8 put: (1 &lt;&lt; self pinnedBitShift)<br>
&gt;                                  + (self wordIndexableFormat &lt;&lt; self formatShift)<br>
&gt;                                  + self segmentBridgePun;<br>
&gt; +        longAt: address + 12 put: self numSlotsMask &lt;&lt; self numSlotsHalfShift<br>
&gt; +                                + (1 &lt;&lt; self markedBitHalfShift)!<br>
&gt; -            longAt: address + 12 put: self numSlotsMask &lt;&lt; self numSlotsHalfShift!<br>
&gt;<br>
&gt; Item was removed:<br>
&gt; - ----- Method: Spur32BitMemoryManager&gt;&gt;reInitSegmentBridge: (in category &#39;segments&#39;) -----<br>
&gt; - reInitSegmentBridge: bridgeOop<br>
&gt; -    &quot;On image write the segment manager replaces the header of the bridge<br>
&gt; -     with the size of the following segment.  This method restores that header.&quot;<br>
&gt; -    &lt;var: #numBytes type: #usqLong&gt;<br>
&gt; -    self longAt: bridgeOop put: (1 &lt;&lt; self pinnedBitShift)<br>
&gt; -                                + (self wordIndexableFormat &lt;&lt; self formatShift)<br>
&gt; -                                + self segmentBridgePun;<br>
&gt; -            longAt: bridgeOop + 4 put: self numSlotsMask &lt;&lt; self numSlotsHalfShift!<br>
&gt;<br>
&gt; Item was added:<br>
&gt; + ----- Method: Spur32BitMemoryManager&gt;&gt;sortedFreeObject: (in category &#39;free space&#39;) -----<br>
&gt; + sortedFreeObject: objOop<br>
&gt; +    &quot;A variant of freeObject: that assumes objOop already has its valid number of slots, etc,<br>
&gt; +     but makes sure the freeChunkPrevIndex is valid.&quot;<br>
&gt; +    | bytes treeNode nextNode |<br>
&gt; +    bytes := self bytesInObject: objOop.<br>
&gt; +    totalFreeOldSpace := totalFreeOldSpace + bytes.<br>
&gt; +    self longAt: objOop put: 0.<br>
&gt; +    treeNode := self addToFreeList: objOop bytes: bytes.<br>
&gt; +    treeNode ~= 0 ifTrue:<br>
&gt; +        [self storePointer: self freeChunkPrevIndex ofFreeChunk: objOop withValue: treeNode].<br>
&gt; +    nextNode := self fetchPointer: self freeChunkNextIndex ofObject: objOop.<br>
&gt; +    nextNode ~= 0 ifTrue:<br>
&gt; +        [self storePointer: self freeChunkPrevIndex ofFreeChunk: nextNode withValue: objOop]!<br>
&gt;<br>
&gt; Item was changed:<br>
&gt;  ----- Method: Spur64BitMemoryManager&gt;&gt;initSegmentBridgeWithBytes:at: (in category &#39;segments&#39;) -----<br>
&gt;  initSegmentBridgeWithBytes: numBytes at: address<br>
&gt;      | numSlots |<br>
&gt;      &lt;var: #numBytes type: #usqLong&gt;<br>
&gt;      self assert: (numBytes &gt;= (self baseHeaderSize + self baseHeaderSize)<br>
&gt;              and: [numBytes \\ self allocationUnit = 0]).<br>
&gt;      numSlots := numBytes - self baseHeaderSize - self baseHeaderSize &gt;&gt; self shiftForWord.<br>
&gt;      self longAt: address<br>
&gt;              put: self numSlotsMask &lt;&lt; self numSlotsFullShift + numSlots;<br>
&gt;          longAt: address + self baseHeaderSize<br>
&gt;              put: (self numSlotsMask &lt;&lt; self numSlotsFullShift)<br>
&gt;                  + (1 &lt;&lt; self pinnedBitShift)<br>
&gt;<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>