[Vm-dev] VM Maker: VMMaker.oscog.seperateMarking-WoC.3257.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Aug 31 19:01:10 UTC 2022


Tom Braun uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-WoC.3257.mcz

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

Name: VMMaker.oscog.seperateMarking-WoC.3257
Author: WoC
Time: 31 August 2022, 9:00:41.089802 pm
UUID: d53709dc-bdaf-487e-bb8b-e47510bf5cc6
Ancestors: VMMaker.oscog.seperateMarking-WoC.3256

- small refactoring in Compactor
- mark forwarders if neccessary so they get not garbage collected early

=============== Diff against VMMaker.oscog.seperateMarking-WoC.3256 ===============

Item was changed:
+ ----- Method: SpurGarbageCollector>>initialize (in category 'initialize-release') -----
- ----- Method: SpurGarbageCollector>>initialize (in category 'nil') -----
  initialize
  
  	allocatorShouldAllocateBlack := false!

Item was added:
+ ----- Method: SpurGarbageCollector>>maybeModifyForwarder: (in category 'object creation barriers') -----
+ maybeModifyForwarder: objOop
+ 
+ 	<doNotGenerate>!

Item was changed:
+ ----- Method: SpurGarbageCollector>>maybeModifyGCFlagsOf: (in category 'object creation barriers') -----
- ----- Method: SpurGarbageCollector>>maybeModifyGCFlagsOf: (in category 'as yet unclassified') -----
  maybeModifyGCFlagsOf: objOop
  
  	<doNotGenerate>!

Item was added:
+ ----- Method: SpurIncrementalCompactor>>cannotBeCompacted: (in category 'as yet unclassified') -----
+ cannotBeCompacted: segInfo
+ 
+ 	^ (self isSegmentBeingCompacted: segInfo) or: [segInfo containsPinned or: [manager segmentManager isEmptySegment: segInfo]]!

Item was changed:
  ----- Method: SpurIncrementalCompactor>>compactSegment:freeStart:segIndex: (in category 'incremental compaction') -----
  compactSegment: segInfo freeStart: initialFreeStart segIndex: segIndex
  	<var: 'segInfo' type: #'SpurSegmentInfo *'>
  	
+ 	| currentEntity fillStart bytesToCopy bridge |
- 	| currentEntity fillStart bytesToCopy bridge copy |
  	fillStart := initialFreeStart.
  	bridge := manager segmentManager bridgeFor: segInfo.
  	currentEntity := manager objectStartingAt: segInfo segStart.
  	
  	self deny: segIndex = 0. "Cannot compact seg 0"
  	[self oop: currentEntity isLessThan: bridge] whileTrue:
  		[(manager isFreeObject: currentEntity)
  			ifTrue: 
  				[manager detachFreeObject: currentEntity.
  				 "To avoid confusing too much Spur (especially the leak/free checks), we mark the free chunk as a word object."
  				 manager set: currentEntity classIndexTo: manager wordSizeClassIndexPun formatTo: manager wordIndexableFormat]
  			ifFalse: 
  				["During the mutator runs new forwarding references can be created. Ignore them as they get resolved with the other forwarders in this segment in the next marking pass"
  				(manager isForwarded: currentEntity) not
  					ifTrue: ["Copy the object in segmentToFill and replace it by a forwarder."
- 						self assert: (manager isPinned: currentEntity) not. 
  						bytesToCopy := manager bytesInBody: currentEntity. 
  						
+ 						self migrate: currentEntity sized: bytesToCopy to: fillStart.
- 						 manager memcpy: fillStart asVoidPointer _: (manager startOfObject: currentEntity) asVoidPointer _: bytesToCopy.
  						
- 						 copy := manager objectStartingAt: fillStart.
- 						 (manager isRemembered: copy) ifTrue: 
- 							["copy has the remembered bit set, but is not in the remembered table."
- 							 manager setIsRememberedOf: copy to: false.
- 							 scavenger remember: copy].
- 						
- 						 manager forward: currentEntity to: (manager objectStartingAt: fillStart).
- 						
  						fillStart := fillStart + bytesToCopy.
  						self assert: (self oop: fillStart isLessThan: (segmentToFill segLimit - manager bridgeSize))]].
  		
  		 currentEntity := manager objectAfter: currentEntity limit: manager endOfMemory].
  	
  	self assert: currentEntity = bridge.
  	currentSegment := currentSegment + 1.
  	^ fillStart!

Item was changed:
  ----- Method: SpurIncrementalCompactor>>doIncrementalCompact (in category 'incremental compaction') -----
  doIncrementalCompact
  
  	| segInfo |
  	currentSegment to: manager numSegments - 1 do:
  		[:i | 
  		 segInfo := self addressOf: (manager segmentManager segments at: i).
  		(self isSegmentBeingCompacted: segInfo)
  			ifTrue: [currentSegment := i.
  				
+ 				coInterpreter cr; 
+ 					print: 'Compact from: '; printNum: segInfo segStart; 
+ 					print: '  to: '; printNum: segInfo segStart + segInfo segSize; 
+ 					print: '  into: ' ; printNum: segmentToFill segStart; tab; flush.
- 				coInterpreter cr; print: 'Compact from: '; printNum: segInfo segStart; print: '  to: '; printNum: segInfo segStart + segInfo segSize; print: '  into: ' ; printNum: segmentToFill segStart; tab; flush.
  				
  				currentHeapPointer := self compactSegment: segInfo freeStart: currentHeapPointer segIndex: i.
  				self assert: manager totalFreeOldSpace = manager totalFreeListBytes.
  				
  				self flag: #Todo. "for now we compact on segment at a time"
  				^ currentSegment = (manager numSegments - 1)
  					ifTrue: [true]
  					ifFalse: [false]]].
  	^ true!

Item was changed:
  ----- Method: SpurIncrementalCompactor>>findNextSegmentToCompact (in category 'compaction planning') -----
  findNextSegmentToCompact
  	"Answers the next segment to compact or nil if none.
  	  The next segment to compact:
  	 - cannot be segment 0 (Segment 0 has specific objects 
  	  (nil, true, etc.) and special size computed at start-up 
  	  that we don't want to deal with)
  	 - cannot have a high occupation rate (> MaxOccupationForCompaction)"
  	| leastOccupied leastOccupiedSegment tempOccupied segInfo |
  	<var: 'segInfo' type: #'SpurSegmentInfo *'>
  	leastOccupied := 16rFFFF.
  	1 to: manager numSegments - 1 do:
  		[:i|
  		 segInfo := self addressOf: (manager segmentManager segments at: i).
+ 		 (self cannotBeCompacted: segInfo)
- 		 ((self isSegmentBeingCompacted: segInfo) or: [segInfo containsPinned or: [manager segmentManager isEmptySegment: segInfo] ])
  			ifFalse: 
  				[(tempOccupied := self occupationOf: segInfo) <= leastOccupied
  					ifTrue: [ leastOccupied := tempOccupied.
  							 leastOccupiedSegment := segInfo ]]].
  	leastOccupied > MaxOccupationForCompaction ifTrue:
  		[^self cCoerceSimple: nil to: #'SpurSegmentInfo *'].
  	^leastOccupiedSegment!

Item was added:
+ ----- Method: SpurIncrementalCompactor>>migrate:sized:to: (in category 'as yet unclassified') -----
+ migrate: obj sized: bytesToCopy to: address
+ 
+ 	| copy |
+ 	self assert: (manager isPinned: obj) not. 
+ 	
+ 	manager memcpy: address asVoidPointer _: (manager startOfObject: obj) asVoidPointer _: bytesToCopy.
+ 	
+ 	copy := manager objectStartingAt: address.
+ 	 (manager isRemembered: copy) ifTrue: 
+ 		["copy has the remembered bit set, but is not in the remembered table."
+ 		 manager setIsRememberedOf: copy to: false.
+ 		 scavenger remember: copy].
+ 	
+ 	 manager forward: obj to: (manager objectStartingAt: address). 
+ 	
+ 	^ copy!

Item was changed:
  ----- Method: SpurIncrementalGarbageCollector>>doIncrementalCollect (in category 'as yet unclassified') -----
  doIncrementalCollect
  	
  	phase = InMarkingPhase
  		ifTrue: [
  			coInterpreter cr; print: 'start marking '; tab; flush.
  			marker incrementalMarkObjects
  				ifTrue: [
  					manager allPastSpaceObjectsDo: [:obj | self assert: (manager isWhite: obj)].
+ 					manager allOldSpaceObjectsDo: [:ea | (manager isForwarded: ea) ifTrue: [self halt] ].
  					
  					"when sweeping the mutator needs to allocate new objects black as we do not have any information about them.
  					We only know if they should get swept after the next marking -> keep them alive for this cycle"
  					self allocatorShouldAllocateBlack: true.
  					compactor setInitialSweepingEntity.
  					phase := InSweepingPhase.
  					
  					"marking is done and thus all forwarding references are resolved -> we can use the now free segments that were 
  					compacted during the last cycle"
  					compactor freePastSegmentsAndSetSegmentToFill.
  					
  					coInterpreter cr; print: 'finish marking '; tab; flush.
  					
  					manager 
  						setCheckForLeaks: GCCheckFreeSpace + GCModeFull;
  						runLeakCheckerFor: GCModeFull;
  						checkFreeSpace: GCModeFull.
  						
  					
  					^ self]
  				ifFalse: [coInterpreter cr; print: 'finish marking pass'; tab; flush.manager runLeakCheckerFor: GCModeIncremental]].
  		
  	phase = InSweepingPhase
  		ifTrue: [
  			coInterpreter cr; print: 'start sweeping '; tab; flush.
  			compactor incrementalSweep
  				ifTrue: [
  					self allocatorShouldAllocateBlack: false.
  					manager allOldSpaceObjectsDo: [:ea | self assert: (manager isWhite: ea) ].
  					"self assert: manager allObjectsUnmarked."
  					
  					coInterpreter cr; print: 'finish sweeping '; tab; flush.
  					
  					manager 
  						setCheckForLeaks: GCCheckFreeSpace + GCModeFull;
  						runLeakCheckerFor: GCModeFull;
  						checkFreeSpace: GCModeFull.
  					
  					phase := InCompactingPhase.
  					^ self]].
  		
  	phase = InCompactingPhase
  		ifTrue: [
  			coInterpreter cr; print: 'start compacting '; tab; flush.
  			compactor incrementalCompact
  				ifTrue: [
  					coInterpreter cr; print: 'finish compacting '; tab; flush.
  					manager 
  						setCheckForLeaks: GCCheckFreeSpace + GCModeFull;
  						runLeakCheckerFor: GCModeFull;
  						checkFreeSpace: GCModeFull.
  					
  					phase := InMarkingPhase.
  					^ self]]!

Item was changed:
  ----- Method: SpurIncrementalGarbageCollector>>fullGC (in category 'global') -----
  fullGC
  	"We need to be able to make a full GC, e.g. when we save the image. Use the made progress and finish the collection"
  	
  	"incredible hacky solution. Will later on be replaced with the old collection, but for now use this to keep the state transitions consistent"
  	
  	self assert: manager validObjStacks.
+ 	self halt.
- 	
  	coInterpreter cr; print: 'start fullGC '; tab; flush.
  	
  	coInterpreter setGCMode: GCModeNewSpace.
  	self doScavengeWithoutIncrementalCollect: MarkOnTenure.
  	
  	phase = InMarkingPhase
  		ifTrue: [
  			"end marking"
  			[phase = InMarkingPhase]
  				whileTrue: [self doIncrementalCollect]].
  		
  		"end this collection cycle"
  		[phase ~= InMarkingPhase]
  			whileTrue: [self doIncrementalCollect].
  			
  		"resolve forwarders in young space"
  		coInterpreter setGCMode: GCModeNewSpace.
  		self doScavengeWithoutIncrementalCollect: MarkOnTenure.
  		
  		"mark completely"
  		[phase = InMarkingPhase]
  			whileTrue: [self doIncrementalCollect].
  		"do rest of collection"
  		[phase ~= InMarkingPhase]
  			whileTrue: [self doIncrementalCollect].
  	
  	manager setHeapSizeAtPreviousGC.
  	
  	coInterpreter cr; print: 'end fullGC '; tab; flush.
  	
  	^(manager freeLists at: 0) ~= 0
  		ifTrue: [manager bytesInBody: manager findLargestFreeChunk]
  		ifFalse: [0]!

Item was added:
+ ----- Method: SpurIncrementalGarbageCollector>>maybeModifyForwarder: (in category 'object creation barriers') -----
+ maybeModifyForwarder: objOop
+ 
+ 	"mark forwarders so they do not get garbage collected before they can get resolved. 
+ 	1. Does only apply to marking because only in this phase we can overlook forwarding references to be resolved (e.g. when 
+ 	the mutator runs after the first marking pass and an already black object gets a forwarding pointer -> it will not be followed in this
+ 	marking pass and during sweeping the forwardgin pointer will get removes).
+ 	2. Does not apply to sweeping or compacting because the forwarder is set on the header of the original object, which already includes 
+ 	the correcty set mark bit"
+ 	self assert: (manager isForwarded: objOop).
+ 	((manager isOldObject: objOop) and: [phase = InMarkingPhase])
+ 		ifTrue: [manager setIsMarkedOf: objOop to: true]!

Item was changed:
+ ----- Method: SpurIncrementalGarbageCollector>>maybeModifyGCFlagsOf: (in category 'object creation barriers') -----
- ----- Method: SpurIncrementalGarbageCollector>>maybeModifyGCFlagsOf: (in category 'as yet unclassified') -----
  maybeModifyGCFlagsOf: objOop
  
  	"when allocating a new object behind the current sweeping hight mark it should be allocated black so it does not get garbage
  	collected although we do not know if this is correct"
  	<inline: true>
  	((manager isOldObject: objOop) and: [allocatorShouldAllocateBlack and: [objOop >= compactor currentSweepingEntity]])
  		ifTrue: [manager setIsMarkedOf: objOop to: true]!

Item was changed:
  ----- Method: SpurMemoryManager>>forward:to: (in category 'become implementation') -----
  forward: obj1 to: obj2
  	self set: obj1 classIndexTo: self isForwardedObjectClassIndexPun formatTo: self forwardedFormat.
  	self cppIf: IMMUTABILITY ifTrue: [ self setIsImmutableOf: obj1 to: false ].
  	self storePointer: 0 ofForwarder: obj1 withValue: obj2.
+ 	gc maybeModifyForwarder: obj1. 
  	"For safety make sure the forwarder has a slot count that includes its contents."
  	(self rawNumSlotsOf: obj1) = 0 ifTrue:
  		[self rawNumSlotsOf: obj1 put: 1]!



More information about the Vm-dev mailing list