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

commits at source.squeak.org commits at source.squeak.org
Sun Sep 29 19:06:39 UTC 2013


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

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

Name: VMMaker.oscog-eem.417
Author: eem
Time: 29 September 2013, 12:03:30.837 pm
UUID: e868c34a-af52-4474-bf0f-f4a52dafd767
Ancestors: VMMaker.oscog-eem.416

Fix ephemeron processing.  Any ephemerons reached during
scavenging should be copied to future space.  Therefore their
contents must not be scavenged if their keys are as yet unreached.
So replace numStrongSlotsOf: with
numStrongSlotsOf:ephemeronInactiveIf:.
Further, move forwarding through ephemeron keys into
isScavengeSurvivor:, and make ephemeron assert in
scavengeReferentsOf: more accurate. Ephemeron must be either
inactive or on the ephemeronList.

Use numFixedSlotsOf: instead of numStrongSlotsOf: in
processWeakSurvivor:.

Fix tenuringThreshold computation,
    (pastSpace size * (1 - tenuringProportion)
not pastSpace size * tenuringProportion.

Provide some debugging conveniences.

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

Item was changed:
  ----- Method: SpurGenerationScavenger>>computeTenuringThreshold (in category 'scavenger') -----
  computeTenuringThreshold
  	| fractionSurvived |
  	<var: 'fractionSurvived' type: #float>
  	fractionSurvived := (futureSurvivorStart - futureSpace start) asFloat
  						/ (futureSpace limit - futureSpace start).
  	tenuringThreshold := fractionSurvived > 0.9
+ 							ifTrue: [((pastSpace limit - pastSpace start) * (1.0 - tenuringProportion)) rounded + pastSpace start]
- 							ifTrue: [((pastSpace limit - pastSpace start) * tenuringProportion) rounded + pastSpace start]
  							ifFalse: [0]!

Item was added:
+ ----- Method: SpurGenerationScavenger>>futureSpaceObjectsDo: (in category 'debug support') -----
+ futureSpaceObjectsDo: aBlock
+ 	| obj |
+ 	futureSurvivorStart > futureSpace start ifTrue:
+ 		[obj := manager objectStartingAt: futureSpace start.
+ 		 [obj < futureSurvivorStart] whileTrue:
+ 			[aBlock value: obj.
+ 			 obj := manager objectAfter: obj limit: futureSurvivorStart]]!

Item was added:
+ ----- Method: SpurGenerationScavenger>>is:onWeaklingList: (in category 'weakness and ephemerality') -----
+ is: oop onWeaklingList: listHead
+ 	| corpse |
+ 	corpse := self firstCorpse: listHead.
+ 	[corpse notNil] whileTrue:
+ 		[oop = (manager followForwarded: corpse) ifTrue:
+ 			[^true].
+ 		 corpse := self nextCorpseOrNil: corpse].
+ 	^false!

Item was changed:
  ----- Method: SpurGenerationScavenger>>isScavengeSurvivor: (in category 'weakness and ephemerality') -----
  isScavengeSurvivor: oop
  	"Answer whether the oop has survived a scavenge.  This is equivalent to
+ 		| target |
+ 		(manager isImmediate: oop) ifTrue:
+ 			[^true].
+ 		target := (manager isForwarded: oop)
+ 					ifTrue: [manager followForwarded: oop]
+ 					ifFalse: [oop].
+ 	 	^((manager isInEden: target)
+ 		  or: [(manager isInPastSpace: target)]) not"
+ 	| target |
+ 	(manager isImmediate: oop) ifTrue:
+ 		[^true].
+ 	target := (manager isForwarded: oop)
+ 				ifTrue: [manager followForwarded: oop]
+ 				ifFalse: [oop].
+ 	^(manager isYoung: target) not
+ 	  or: [manager isInFutureSpace: target]!
- 	 	^(manager isImmediate: oop)
- 		  or: [((manager isInEden: oop) or: [(manager isInPastSpace: oop)]) not]"
- 	^(manager isImmediate: oop)
- 	  or: [(manager isYoung: oop) not
- 	  or: [(manager isInFutureSpace: oop)]]!

Item was changed:
  ----- Method: SpurGenerationScavenger>>noUnfiredEphemeronsAtEndOfRememberedSet (in category 'weakness and ephemerality') -----
  noUnfiredEphemeronsAtEndOfRememberedSet
  	"For assert checking only."
  	numRememberedEphemerons to: rememberedSetSize - 1 do:
+ 		[:i| | referrer |
- 		[:i| | referrer key |
  		referrer := rememberedSet at: i.
  		(manager isEphemeron: referrer) ifTrue:
+ 			[(self isScavengeSurvivor: (manager keyOfEphemeron: referrer)) ifFalse:
- 			[key := manager keyOfEphemeron: referrer.
- 			 (manager isForwarded: key) ifTrue:
- 				[key := manager followForwarded: key].
- 			(self isScavengeSurvivor: key) ifFalse:
  				[^false]]].
  	^true!

Item was added:
+ ----- Method: SpurGenerationScavenger>>printWeaklingList: (in category 'debug support') -----
+ printWeaklingList: listHead
+ 	"Print the objects on either the weakList or the ephemeronList."
+ 	| corpse |
+ 	corpse := self firstCorpse: listHead.
+ 	corpse ifNil:
+ 		[coInterpreter print: 'empty'; cr.
+ 		 ^self].
+ 	[corpse notNil] whileTrue:
+ 		[coInterpreter printHexnp: corpse; print: ' -> '; shortPrintOop: (manager followForwarded: corpse).
+ 		 corpse := self nextCorpseOrNil: corpse]!

Item was changed:
  ----- Method: SpurGenerationScavenger>>processWeakSurvivor: (in category 'weakness and ephemerality') -----
  processWeakSurvivor: weakObj
  	"Process a weak survivor on the weakList.  Those of its fields
  	 which have not survived the scavenge should be nilled, and if any
  	 are, the coInterpreter should be informed via signalFinalization:."
  	| weakObjShouldMourn |
  	weakObjShouldMourn := false.
+ 	(manager numFixedSlotsOf: weakObj)
- 	(manager numStrongSlotsOf: weakObj)
  		to: (manager numSlotsOf: weakObj) - 1
  		do: [:i| | referent |
  			referent := manager fetchPointer: i ofObject: weakObj.
  			"Referent could be forwarded due to scavenging or a become:, don't assume."
  			((manager isNonImmediate: referent)
  			and: [manager isForwarded: referent]) ifTrue:
  				[referent := manager followForwarded: referent.
  				 (self isScavengeSurvivor: referent) ifTrue:
  					[manager storePointer: i ofObject: weakObj withValue: referent]].
  			(self isScavengeSurvivor: referent)
  				ifFalse:
  					[weakObjShouldMourn := true.
  					 manager
  						storePointerUnchecked: i
  						ofObject: weakObj
  						withValue: manager nilObject]
  				ifTrue:
  					[self assert: referent = (manager fetchPointer: i ofObject: weakObj)]].
  	weakObjShouldMourn ifTrue:
  		[coInterpreter signalFinalization: weakObj]!

Item was changed:
  ----- Method: SpurGenerationScavenger>>scavengeReferentsOf: (in category 'scavenger') -----
  scavengeReferentsOf: referrer
  	"scavengeReferentsOf: referrer inspects all the pointers in referrer.
  	 If any are new objects, it has them moved to FutureSurvivorSpace,
  	 and answers truth. If there are no new referents, it answers falsity.
  	 To handle weak arrays only scavenge string slots and answer true
  	 if the referrer is weak, so that it won't be removed from the
  	 remembered set until later."
  	| foundNewReferent |
  	"forwarding objects should be followed by callers,
  	 unless the forwarder is a root in the remembered table."
  	self assert: ((manager isForwarded: referrer) not
  				or: [manager isRemembered: referrer]).
  	"unscanned ephemerons should be scanned later."
  	self assert: ((manager isEphemeron: referrer) not
+ 				or: [(self isScavengeSurvivor: (manager keyOfEphemeron: referrer))
+ 				or: [self is: referrer onWeaklingList: ephemeronList]]).
- 				or: [| key |
- 					key := manager keyOfEphemeron: referrer.
- 					(manager isForwarded: key) ifTrue:
- 						[key := manager followForwarded: key].
- 					self isScavengeSurvivor: key]).
  	foundNewReferent := false.
+ 	0 to: (manager numStrongSlotsOf: referrer ephemeronInactiveIf: #isScavengeSurvivor:) - 1
+ 	   do: [:i| | referent newLocation |
- 	0 to: (manager numStrongSlotsOf: referrer) - 1 do:
- 		[:i| | referent newLocation |
  		referent := manager fetchPointer: i ofMaybeForwardedObject: referrer.
  		(manager isNonImmediate: referent) ifTrue:
  			["a forwarding pointer could be because of become: or scavenging."
  			 referent := (manager isForwarded: referent)
  								ifTrue: [manager followForwarded: referent]
  								ifFalse: [referent].
  			 (manager isYoung: referent)
  				ifTrue:
  					["if target is already in future space forwarding pointer was due to a become:."
  					 (manager isInFutureSpace: referent)
  						ifTrue: [newLocation := referent]
  						ifFalse:
  							[(manager isForwarded: referent)
  								ifTrue: [self halt. "can this even happen?"
  									newLocation := manager followForwarded: referent]
  								ifFalse: [newLocation := self copyAndForward: referent]].
  					 (manager isYoung: newLocation) ifTrue:
  						[foundNewReferent := true].
  					 manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: newLocation]
  				ifFalse:
  					[manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: referent]]].
  	^foundNewReferent or: [manager isWeakNonImm: referrer]!

Item was changed:
  ----- Method: SpurGenerationScavenger>>scavengeUnfiredEphemeronsInRememberedSet (in category 'weakness and ephemerality') -----
  scavengeUnfiredEphemeronsInRememberedSet
  	"There are ephemerons to be scavenged in the remembered set.
  	 Scavenge any with unfired (live) keys, removing them from the
  	 unscavenged ephemerons, and from the set if they no longer refer
  	 to new objects, and answer if any with unfired keys were found."
+ 	| unfiredEphemeronsScavenged i referrer hasNewReferents |
- 	| unfiredEphemeronsScavenged i referrer key hasNewReferents |
  	unfiredEphemeronsScavenged := false.
  	i := 0.
  	[i < numRememberedEphemerons] whileTrue:
  		[referrer := rememberedSet at: i.
  		 self assert: (manager isEphemeron: referrer).
+ 		 (self isScavengeSurvivor: (manager keyOfEphemeron: referrer))
- 		 key := manager keyOfEphemeron: referrer.
- 		 (manager isOopForwarded: key) ifTrue:
- 			[key := manager followForwarded: key].
- 		 (self isScavengeSurvivor: key)
  			ifTrue:
  				[unfiredEphemeronsScavenged := true.
  				 hasNewReferents := self scavengeReferentsOf: referrer.
  				 "remove from unscanned ephemerons in set by swapping with last ephemeron"
  				 numRememberedEphemerons := numRememberedEphemerons - 1.
  				 rememberedSet
  					at: i
  					put: (rememberedSet at: numRememberedEphemerons).
  				 hasNewReferents
  					ifTrue: "keep in set"
  						[rememberedSet
  							at: numRememberedEphemerons
  							put: referrer]
  					ifFalse: "remove from set by overwriting with next-to-be scanned"
  						[previousRememberedSetSize := previousRememberedSetSize - 1.
  						 rememberedSetSize := rememberedSetSize - 1.
  						 rememberedSet
  							at: numRememberedEphemerons
  								put: (rememberedSet at: previousRememberedSetSize);
  							at: previousRememberedSetSize
  								put: (rememberedSet at: rememberedSetSize).
  						 manager setIsRememberedOf: referrer to: false]]
  				ifFalse:
  					[i := i + 1]].
  	^unfiredEphemeronsScavenged!

Item was changed:
  ----- Method: SpurGenerationScavenger>>scavengeUnfiredEphemeronsOnEphemeronList (in category 'weakness and ephemerality') -----
  scavengeUnfiredEphemeronsOnEphemeronList
  	"There may be ephemerons to be scavenged on the ephemeronList.
  	 Scavenge any with unfired (live) keys, removing them from the
  	 list, and answer if any with unfired keys were found."
  	| unfiredEphemeronsScavenged corpseOffset previousCorpse |
  	ephemeronList ifNil:
  		[^false].
  	unfiredEphemeronsScavenged := false.
  	corpseOffset := ephemeronList.
  	[corpseOffset ~= 0] whileTrue:
+ 		[| ephemeronCorpse ephemeron nextCorpseOffset  |
- 		[| ephemeronCorpse ephemeron nextCorpseOffset key |
  		 ephemeronCorpse := self corpseForCorpseOffset: corpseOffset.
  		 self assert: (manager isForwarded: ephemeronCorpse).
  		 ephemeron := manager followForwarded: ephemeronCorpse.
  		 nextCorpseOffset := self nextCorpseOffset: ephemeronCorpse.
+ 		 (self isScavengeSurvivor: (manager keyOfEphemeron: ephemeron))
- 		 key := manager keyOfEphemeron: ephemeron.
- 		 (manager isOopForwarded: key) ifTrue:
- 			[key := manager followForwarded: key].
- 		 (self isScavengeSurvivor: key)
  			ifTrue:
  				[corpseOffset = ephemeronList
  					ifTrue: [ephemeronList := nextCorpseOffset ~= 0 ifTrue: [nextCorpseOffset]]
  					ifFalse: [self setCorpseOffsetOf: previousCorpse to: nextCorpseOffset].
  				 unfiredEphemeronsScavenged := true.
  				 self cCoerceSimple: (self scavengeReferentsOf: ephemeron) to: #void]
  			ifFalse:
  				[previousCorpse := ephemeronCorpse].
  		 corpseOffset := nextCorpseOffset].
  	^unfiredEphemeronsScavenged!

Item was changed:
  ----- Method: SpurGenerationScavenger>>scavengerTenuringThreshold: (in category 'accessing') -----
  scavengerTenuringThreshold: aProportion "(Slang flattens so need unique selectors)"
  	<var: 'aProportion' type: #float>
  	tenuringProportion := aProportion.
  	tenuringThreshold := aProportion = 0.0
  							ifTrue: [0]
+ 							ifFalse: [((pastSpace limit - pastSpace start) * (1.0 - aProportion)) rounded + pastSpace start]!
- 							ifFalse: [((pastSpace limit - pastSpace start) * aProportion) rounded + pastSpace start]!

Item was added:
+ ----- Method: SpurMemoryManager>>isScavengeSurvivor: (in category 'generation scavenging') -----
+ isScavengeSurvivor: oop
+ 	<doNotGenerate>
+ 	^scavenger isScavengeSurvivor: oop!

Item was added:
+ ----- Method: SpurMemoryManager>>numFixedSlotsOf: (in category 'object format') -----
+ numFixedSlotsOf: objOop
+ 	<inline: true>
+ 	<asmLabel: false>
+ 	^self fixedFieldsOfClassFormat: (self formatOfClass: (self fetchClassOfNonImm: objOop))!

Item was added:
+ ----- Method: SpurMemoryManager>>numStrongSlotsOf:ephemeronInactiveIf: (in category 'object access') -----
+ numStrongSlotsOf: objOop ephemeronInactiveIf: criterion
+ 	"Answer the number of strong pointer fields in the given object.
+ 	 Works with CompiledMethods, as well as ordinary objects."
+ 	<api>
+ 	<var: 'criterion' declareC: 'int (*criterion)(sqInt key)'>
+ 	<inline: true>
+ 	<asmLabel: false>
+ 	| fmt numSlots  contextSize numLiterals |
+ 	fmt := self formatOf: objOop.
+ 	fmt <= self lastPointerFormat ifTrue:
+ 		[numSlots := self numSlotsOf: objOop.
+ 		 fmt <= self arrayFormat ifTrue:
+ 			[^numSlots].
+ 		 fmt = self indexablePointersFormat ifTrue:
+ 			[(self isContextNonImm: objOop) ifTrue:
+ 				["contexts end at the stack pointer"
+ 				contextSize := coInterpreter fetchStackPointerOf: objOop.
+ 				^CtxtTempFrameStart + contextSize].
+ 			 ^numSlots].
+ 		 fmt = self weakArrayFormat ifTrue:
+ 			[^self fixedFieldsOfClass: (self fetchClassOfNonImm: objOop)].
+ 		 self assert: fmt = self ephemeronFormat.
+ 		 ^(self perform: criterion with: (self keyOfEphemeron: objOop))
+ 			ifTrue: [numSlots]
+ 			ifFalse: [0]].
+ 	fmt = self forwardedFormat ifTrue: [^1].
+ 	fmt < self firstCompiledMethodFormat ifTrue: [^0]. "no pointers"
+ 
+ 	"CompiledMethod: contains both pointers and bytes"
+ 	numLiterals := coInterpreter literalCountOf: objOop.
+ 	^numLiterals + LiteralStart!



More information about the Vm-dev mailing list