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