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

commits at source.squeak.org commits at source.squeak.org
Mon May 23 22:51:43 UTC 2016


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

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

Name: VMMaker.oscog-eem.1865
Author: eem
Time: 23 May 2016, 3:49:52.425548 pm
UUID: 2aa4b0e0-004d-4599-896a-084a749a2c47
Ancestors: VMMaker.oscog-eem.1861

Fix two bugs in ephemerons (found by Gille Polito - thanks!).

1. obj stack extension must happen with marking set to true if new pages aren't to be GC'ed.  So move the assignments to marking out into markObjects: where they can surround nilUnmarkedWeaklingSlots.

2. fireAllUnscannedEphemerons needs to enumerate the unscannedEphemerons set properly, an oop at a time.

Use bytesPerOop instead of wordSize throughout unscannedEphemerons access for consistency.

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

Item was changed:
  ----- Method: SpurMemoryManager>>allUnscannedEphemeronsAreActive (in category 'weakness and ephemerality') -----
  allUnscannedEphemeronsAreActive
+ 	unscannedEphemerons start to: unscannedEphemerons top - self bytesPerOop by: self bytesPerOop do:
- 	unscannedEphemerons start to: unscannedEphemerons top - self bytesPerOop do:
  		[:p| | key |
  		key := self keyOfEphemeron: (self longAt: p).
  		((self isImmediate: key) or: [self isMarked: key]) ifTrue:
  			[^false]].
  	^true!

Item was changed:
  ----- Method: SpurMemoryManager>>fireAllUnscannedEphemerons (in category 'weakness and ephemerality') -----
  fireAllUnscannedEphemerons
  	self assert: (self noUnscannedEphemerons) not.
  	self assert: self allUnscannedEphemeronsAreActive.
+ 	unscannedEphemerons start to: unscannedEphemerons top - self bytesPerOop by: self bytesPerOop do:
- 	unscannedEphemerons start to: unscannedEphemerons top - self wordSize do:
  		[:p|
  		coInterpreter fireEphemeron: (self longAt: p)]!

Item was changed:
  ----- Method: SpurMemoryManager>>markAccessibleObjectsAndFireEphemerons (in category 'gc - global') -----
  markAccessibleObjectsAndFireEphemerons
+ 	self assert: marking.
  	self assert: self validClassTableRootPages.
  	self assert: segmentManager allBridgesMarked.
  	self cCode: [] "for debugging markAndTrace: set (MarkStackRecord := OrderedCollection new)"
  		inSmalltalk: [MarkStackRecord ifNotNil: [MarkStackRecord resetTo: 1]].
  
- 	marking := true.
  	"This must come first to enable stack page reclamation.  It clears
  	  the trace flags on stack pages and so must precede any marking.
  	  Otherwise it will clear the trace flags of reached pages."
  	coInterpreter initStackPageGC.
  	self markAndTraceHiddenRoots.
  	self markAndTraceExtraRoots.
  	self assert: self validClassTableRootPages.
  	coInterpreter markAndTraceInterpreterOops: true.
  	self assert: self validObjStacks.
  	self markWeaklingsAndMarkAndFireEphemerons.
+ 	self assert: self validObjStacks!
- 	self assert: self validObjStacks.
- 	marking := false!

Item was changed:
  ----- Method: SpurMemoryManager>>markAllUnscannedEphemerons (in category 'weakness and ephemerality') -----
  markAllUnscannedEphemerons
  	"After firing the unscanned ephemerons we must scan-mark them.
  	 The wrinkle is that doing so may add more ephemerons to the set."
  	| ptr |
  	self assert: (self noUnscannedEphemerons) not.
  	self assert: self allUnscannedEphemeronsAreActive.
  	ptr := unscannedEphemerons top - self wordSize.
  	[ptr >= unscannedEphemerons start] whileTrue:
  		[| ephemeron key |
  		 key := self followedKeyOfEphemeron: (ephemeron := self longAt: ptr).
  		 self
  			markAndTrace: key;
  			markAndTrace: ephemeron.
+ 		 unscannedEphemerons top: unscannedEphemerons top - self bytesPerOop.
- 		 unscannedEphemerons top: unscannedEphemerons top - self wordSize.
  		 ptr < unscannedEphemerons top ifTrue:
  			["not the last entry; remove it by overwriting it with the last
  			  ephemeron (which must have been newly added by markAndTrace:)."
  			 self longAt: ptr put: (self longAt: unscannedEphemerons top)].
+ 		ptr := ptr - self bytesPerOop]!
- 		ptr := ptr - self wordSize]!

Item was changed:
  ----- Method: SpurMemoryManager>>markInactiveEphemerons (in category 'weakness and ephemerality') -----
  markInactiveEphemerons
  	"Go through the unscanned ephemerons, marking the inactive ones, and
  	 removing them from the unscanned ephemerons. Answer if any inactive
  	 ones were found. We cannot fire the ephemerons until all are found to
  	 be active since scan-marking an inactive ephemeron later in the set may
  	 render a previously-observed active ephemeron as inactive."
  	| foundInactive ptr |
  	foundInactive := false.
  	ptr := unscannedEphemerons start.
  	[ptr < unscannedEphemerons top] whileTrue:
  		[| ephemeron key |
  		 key := self followedKeyOfEphemeron: (ephemeron := self longAt: ptr).
  		 ((self isImmediate: key) or: [self isMarked: key])
  			ifTrue:
  				[foundInactive := true.
  				 "Now remove the inactive ephemeron from the set, and scan-mark it.
  				  Scan-marking it may add more ephemerons to the set."
+ 				 unscannedEphemerons top: unscannedEphemerons top - self bytesPerOop.
- 				 unscannedEphemerons top: unscannedEphemerons top - self wordSize.
  				 unscannedEphemerons top > ptr ifTrue:
  					[self longAt: ptr put: (self longAt: unscannedEphemerons top)].
  				 self markAndTrace: ephemeron]
  			ifFalse:
+ 				[ptr := ptr + self bytesPerOop]].
- 				[ptr := ptr + self wordSize]].
  	^foundInactive!

Item was changed:
  ----- Method: SpurMemoryManager>>markObjects: (in category 'gc - global') -----
  markObjects: objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged
  	<inline: #never> "for profiling"
  	"Mark all accessible objects.  objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged
  	 is true if all objects are unmarked and/or if unmarked classes shoud be removed from the class table."
  	"If the incremental collector is running mark bits may be set; stop it and clear them if necessary."
  	self cCode: '' inSmalltalk: [coInterpreter transcript nextPutAll: 'marking...'; flush].
  	self runLeakCheckerFor: GCModeFull.
  
  	self shutDownIncrementalGC: objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged.
  	self initializeUnscannedEphemerons.
  	self initializeMarkStack.
  	self initializeWeaklingStack.
+ 	marking := true.
  	self markAccessibleObjectsAndFireEphemerons.
  	self expungeDuplicateAndUnmarkedClasses: objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged.
+ 	self nilUnmarkedWeaklingSlots.
+ 	marking := false!
- 	self nilUnmarkedWeaklingSlots!

Item was changed:
  ----- Method: SpurMemoryManager>>nilUnmarkedWeaklingSlots (in category 'weakness and ephemerality') -----
  nilUnmarkedWeaklingSlots
  	"Nil the unmarked slots in the weaklings on the
  	 weakling stack, finalizing those that lost references.
  	 Finally, empty the weaklingStack."
  	<inline: #never> "for profiling"
  	self cCode: '' inSmalltalk: [coInterpreter transcript nextPutAll: 'nilling...'; flush].
  	self eassert: [self allOldMarkedWeakObjectsOnWeaklingStack].
  	weaklingStack = nilObj ifTrue:
  		[^self].
  	self objStack: weaklingStack from: 0 do:
  		[:weakling| | anyUnmarked |
  		anyUnmarked := self nilUnmarkedWeaklingSlotsIn: weakling.
  		anyUnmarked ifTrue:
+ 			["fireFinalization: could grow the mournQueue and if so,
+ 			  additional pages must be marked to avoid being GC'ed."
+ 			 self assert: marking.
+ 			 coInterpreter fireFinalization: weakling]].
- 			[coInterpreter fireFinalization: weakling]].
  	self emptyObjStack: weaklingStack!

Item was changed:
  ----- Method: SpurMemoryManager>>pushOnUnscannedEphemeronsStack: (in category 'weakness and ephemerality') -----
  pushOnUnscannedEphemeronsStack: anEphemeron
  	"Attempt to push anEphemeron on the unscanned ephemerons stack
  	 and answer if the attempt succeeded.  Note that the ephemeron
  	 stack overflowing isn't a disaster; it simply means treating the
  	 ephemeron as strong in this GC cycle."
  	<inline: false>
  	self assert: (self isEphemeron: anEphemeron).
  	unscannedEphemerons top >= unscannedEphemerons limit ifTrue:
  		[^false].
  	self longAt: unscannedEphemerons top put: anEphemeron.
+ 	unscannedEphemerons top: unscannedEphemerons top + self bytesPerOop.
- 	unscannedEphemerons top: unscannedEphemerons top + self wordSize.
  	^true!



More information about the Vm-dev mailing list