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