[Vm-dev] VM Maker: VMMaker.oscog-eem.1118.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Mar 25 19:43:32 UTC 2015


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1118.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.1118
Author: eem
Time: 25 March 2015, 12:41:22.816 pm
UUID: b055db97-d17b-4dfd-b281-57e8df3faf12
Ancestors: VMMaker.oscog-eem.1117

Work around a compiler bug in 64-bit gcc 4.4.7-4 on
RedHat that elided one f the two assignments to a
corpse's header in threading it onto a weak survivor
list.  Do so by, in 64-bits, performing a single
assignment to the corpse's header, instead of two.

=============== Diff against VMMaker.oscog-eem.1117 ===============

Item was changed:
  ----- Method: SpurGenerationScavenger>>addToEphemeronList: (in category 'weakness and ephemerality') -----
  addToEphemeronList: ephemeronCorpse
  	"ephemeronCorpse is the corpse of an ephemeron that was copied and forwarded.
  	 Later on its surviving copy must be scanned to nil weak references.
  	 Thread the corpse onto the weakList.  Later, the weakList can be followed, and
  	 the forwarding pointer followed to locate the survivor."
+ 	<inline: #never> "Should be too infrequent to lower icache density of copyAndForward:"
- 	<inline: false>
  	| ephemeronListOffset |
  	self assert: (self isScavengeSurvivor: (manager keyOfEphemeron: (manager followForwarded: ephemeronCorpse))) not.
  
  	ephemeronListOffset := ephemeronList ifNil: 0.
  	self setCorpseOffsetOf: ephemeronCorpse to: ephemeronListOffset.
  	ephemeronList := self corpseOffsetOf: ephemeronCorpse.
  	self assert: (self firstCorpse: ephemeronList) = ephemeronCorpse!

Item was changed:
  ----- Method: SpurGenerationScavenger>>addToWeakList: (in category 'weakness and ephemerality') -----
  addToWeakList: weakCorpse
  	"weakCorpse is the corpse of a weak array that was copied and forwarded.
  	 Later on its surviving copy must be scanned to nil weak references.
  	 Thread the corpse onto the weakList.  Later, the weakList can be followed, and
  	 the forwarding pointer followed to locate the survivor."
+ 	<inline: #never> "Should be too infrequent to lower icache density of copyAndForward:"
- 	<inline: false>
  	| weakListOffset |
  
  	weakListOffset := weakList ifNil: 0.
  	self setCorpseOffsetOf: weakCorpse to: weakListOffset.
  	weakList := self corpseOffsetOf: weakCorpse.
  	self assert: (self firstCorpse: weakList) = weakCorpse!

Item was changed:
  ----- Method: SpurGenerationScavenger>>copyToOldSpace:bytes:format: (in category 'scavenger') -----
  copyToOldSpace: survivor bytes: bytesInObject format: formatOfSurvivor
  	"Copy survivor to oldSpace.  Answer the new oop of the object."
+ 	<inline: #never> "Should be too infrequent to lower icache density of copyAndForward:"
- 	<inline: true>
  	| nTenures startOfSurvivor newStart newOop |
  	self assert: (formatOfSurvivor = (manager formatOf: survivor)
  				and: [((manager isMarked: survivor) not or: [tenureCriterion = MarkOnTenure])
  				and: [(manager isPinned: survivor) not
  				and: [(manager isRemembered: survivor) not]]]).
  	nTenures := statTenures.
  	startOfSurvivor := manager startOfObject: survivor.
  	newStart := manager allocateOldSpaceChunkOfBytes: bytesInObject.
  	newStart ifNil:
  		[manager growOldSpaceByAtLeast: 0. "grow by growHeadroom"
  		 newStart := manager allocateOldSpaceChunkOfBytes: bytesInObject.
  		 newStart ifNil:
  			[self error: 'out of memory']].
  	"manager checkFreeSpace."
  	manager mem: newStart asVoidPointer cp: startOfSurvivor asVoidPointer y: bytesInObject.
  	newOop := newStart + (survivor - startOfSurvivor).
  	(manager isAnyPointerFormat: formatOfSurvivor) ifTrue:
  		[self remember: newOop].
  	tenureCriterion = MarkOnTenure ifTrue:
  		[manager setIsMarkedOf: newOop to: true].
  	statTenures := nTenures + 1.
  	^newOop!

Item was changed:
  ----- Method: SpurGenerationScavenger>>setCorpseOffsetOf:to: (in category 'weakness and ephemerality') -----
  setCorpseOffsetOf: corpse to: offset
  	"Set the offset of the corpse's next corpse to offset.  Use the identityHash
  	 and format fields to construct a 27 bit offset through non-future newSpace
  	 and use this to implement the list.  27 bits of 8 byte allocationUnits units is
  	 2 ^ 30 bytes or 1Gb, big enough for newSpace for a good few years yet."
+ 	<inline: true>
- 
  	self assert: (manager isYoung: corpse).
  	self assert: (manager isForwarded: corpse).
+ 	manager wordSize = 4
+ 		ifTrue: "On 64-bit gcc 4.4.7-4 the following is miscompiled at -O2; the first assignment is lost"
+ 			[manager
+ 				setHashBitsOf: corpse
+ 					to: offset >> manager formatFieldWidthShift;
+ 				setFormatOf: corpse
+ 					to: (offset bitAnd: manager formatMask)]
+ 		ifFalse: "So we use the single assignment"
+ 			[self long64At: corpse
+ 				put: (self headerForSlots: (self rawNumSlotsOf: corpse)
+ 						hash: (offset >> manager formatFieldWidthShift)
+ 						format: (offset bitAnd: manager formatMask)
+ 						classIndex: self isForwardedObjectClassIndexPun)]!
- 	manager
- 		setHashBitsOf: corpse
- 			to: offset >> manager formatFieldWidthShift;
- 		setFormatOf: corpse
- 			to: (offset bitAnd: manager formatMask)!

Item was added:
+ ----- Method: SpurMemoryManager>>headerForSlots:hash:format:classIndex: (in category 'header format') -----
+ headerForSlots: numSlots hash: hash format: formatField classIndex: classIndex
+ 	<api>
+ 	"The header format in LSB is
+ 	 MSB:	| 8: numSlots		| (on a byte boundary)
+ 			| 2 bits				|	(msb,lsb = {isMarked,?})
+ 			| 22: identityHash	| (on a word boundary)
+ 			| 3 bits				|	(msb <-> lsb = {isGrey,isPinned,isRemembered}
+ 			| 5: format			| (on a byte boundary)
+ 			| 2 bits				|	(msb,lsb = {isImmutable,?})
+ 			| 22: classIndex		| (on a word boundary) : LSB
+ 	 The remaining bits (7) are used for
+ 		isImmutable	(bit 23)
+ 		isRemembered	(bit 29)
+ 		isPinned		(bit 30)
+ 		isGrey			(bit 31)
+ 		isMarked		(bit 55)
+ 	 leaving 2 unused bits, each next to a 22-bit field, allowing those fields to be
+ 	 expanded to 23 bits..  The three bit field { isGrey, isPinned, isRemembered }
+ 	 is for bits that are never set in young objects.  This allows the remembered
+ 	 table to be pruned when full by using these bits as a reference count of
+ 	 newSpace objects from the remembered table. Objects with a high count
+ 	 should be tenured to prune the remembered table."
+ 	<returnTypeC: #usqLong>
+ 	<inline: true>
+ 	^ ((self cCoerceSimple: numSlots to: #usqLong) << self numSlotsFullShift)
+ 	+ ((self cCoerceSimple: hash to: #usqLong) << self identityHashFullWordShift)
+ 	+ (formatField << self formatShift)
+ 	+ classIndex!

Item was added:
+ ----- Method: SpurMemoryManager>>printHeaderOf: (in category 'debug printing') -----
+ printHeaderOf: objOop
+ 	<api>
+ 	"N.B. No safety bounds checks!!!!  We need to look e.g. at corpses."
+ 	coInterpreter printHexnp: objOop.
+ 	(self numSlotsOfAny: objOop) >= self numSlotsMask
+ 		ifTrue: [coInterpreter
+ 					print: ' hdr16 slotf '; printHexnp: (self numSlotsOfAny: objOop - self allocationUnit);
+ 					print: ' slotc '; printHexnp: (self rawOverflowSlotsOf: objOop); space]
+ 		ifFalse: [coInterpreter print: ' hdr8 slots '; printHexnp: (self numSlotsOfAny: objOop)].
+ 	coInterpreter
+ 		space;
+ 		printChar: ((self isMarked: objOop) ifTrue: [$M] ifFalse: [$m]);
+ 		printChar: ((self isGrey: objOop) ifTrue: [$G] ifFalse: [$g]);
+ 		printChar: ((self isPinned: objOop) ifTrue: [$P] ifFalse: [$p]);
+ 		printChar: ((self isRemembered: objOop) ifTrue: [$R] ifFalse: [$r]);
+ 		printChar: ((self isImmutable: objOop) ifTrue: [$I] ifFalse: [$i]);
+ 		print: ' hash '; printHexnp: (self rawHashBitsOf: objOop);
+ 		print: ' fmt '; printHexnp: (self formatOf: objOop);
+ 		print: ' cidx '; printHexnp: (self classIndexOf: objOop);
+ 		cr!



More information about the Vm-dev mailing list